Site icon RemoteStack

React Native Login and Sign Up with Firebase Auth Tutorial

React Native Firebase authentication tutorial; Firebase offers tons of handy features to build an agile application; the firebase authentication feature is an easy-to-use back-end service that allows user authentication in your app.

This tutorial will illustrate how to build user registration using email and password and login authentication in React Native applications using the Firebase Authentication service.

With the help of Firebase SDK, you can add anonymous sign-in, sign-in with email and password, sign-out, social sign-in such as sign-in with Facebook, sign-in with Twitter, sign-in with Google, sign-in with Apple, and sign-in with phone number.

How to Create Firebase Authentication in React Native

Download Expo React Native App

You have to install Node 12 LTS or greater version in your development system; you can either use npm or yarn to begin installing the Expo CLI.

# npm
npm install -g expo-cli

# yarn
yarn global add expo-cli

Right after that, execute the given command to download the new React Native application.

expo init RnBlogProject

Now, the project is ready, next, dive into the app folder.

cd RnBlogProject

Create Firebase Auth Project

Go to firebase.google.com site, create a new firebase project for react native.

Give a name to your firebase project.

Next, click on the web icon to get started by adding Firebase to your app.

Include Firebase to your web app, register the app and add firebase to your web app; you can also configure Firebase Hosting by selecting on the checkbox.

Now, copy the Firebase SDK you will need it to connect react native app to Firebase.

We are building this react native app on the expo platform, so you have to install firebase using expo.

expo install firebase

In the Expos app, it is required to install the dotenv package.

npm install dotenv

Now, create the .env file at the root of your react native app. Then, replace the firebase credentials with the *, make sure to create this file .

  apiKey: "****************************",
  authDomain: "****************************",
  projectId: "****************************",
  storageBucket: "****************************",
  messagingSenderId: "****************************",
  appId: "****************************"

Look for the app.json file, change the name to app.config.js, you have to update the suggested code within the file.

import 'dotenv/config';

export default {
  expo: {
    name: 'RnBlog',
    slug: 'RnBlog',
    version: '1.0.0',
    orientation: 'portrait',
    icon: './assets/icon.png',
    splash: {
      image: './assets/splash.png',
      resizeMode: 'contain',
      backgroundColor: '#ffffff'
    },
    updates: {
      fallbackToCacheTimeout: 0
    },
    assetBundlePatterns: ['**/*'],
    ios: {
      supportsTablet: true
    },
    android: {
      adaptiveIcon: {
        foregroundImage: './assets/adaptive-icon.png',
        backgroundColor: '#FFFFFF'
      }
    },
    web: {
      favicon: './assets/favicon.png'
    },
    extra: {
      apiKey: process.env.apiKey,
      authDomain: process.env.authDomain,
      projectId: process.env.projectId,
      storageBucket: process.env.storageBucket,
      messagingSenderId: process.env.messagingSenderId,
      appId: process.env.appId
    }
  }
};

In this step, create the config folder inside here, create the firebase.js file and update the given code within the file.

import * as firebase from 'firebase';
import firestore from 'firebase/firestore';

const firebaseConfig = {
  apiKey: "****************************",
  authDomain: "****************************",
  projectId: "****************************",
  storageBucket: "****************************",
  messagingSenderId: "****************************",
  appId: "****************************"
};

firebase.initializeApp(firebaseConfig);

firebase.firestore();

export default firebase;

Set Up Navigation

In this step, you have to install the react native navigation packages.

npm install @react-navigation/native

Also, install the other packages which empowers the navigation in react native.

npm install react-native-gesture-handler react-native-screens react-native-reanimated react-native-safe-area-context @react-native-community/masked-view

In this step, install the stack navigation package. Stack Navigator offers a great way for your app to enable the transition between screens where each new screen is placed on top of a stack.

npm install @react-navigation/stack

We need to enable the navigation in react native app; earlier added the stack navigation library. Now, we will show you how to use it and configure stack navigation in react native.

Next, create components folder, and create the two files inside of it for managing the auth in react native.

=> components/SigninScreen.js

=> components/SignupScreen.js

Head over to the App.js file, import the NavigationContainer, createStackNavigator, and the components define the stack nav method and call the stack navigation.

import * as React from 'react';
import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer } from '@react-navigation/native';

import SigninScreen from './components/SigninScreen';
import SignupScreen from './components/SignupScreen';


const Stack = createStackNavigator();

function StackRnRoutes() {
  return (
     <Stack.Navigator
        initialRouteName="SignupScreen"
        screenOptions={{
          headerTitleAlign: 'center',
          headerStyle: {
            backgroundColor: 'black',
          },
          headerTintColor: '#fff',
          headerTitleStyle :{
            fontWeight: 'bold',
          },
        }}
      >
      <Stack.Screen 
        name="SignupScreen" 
        component={SignupScreen} 
        options={{ title: 'Signup' }}
      />
      <Stack.Screen 
       name="SigninScreen" 
       component={SigninScreen} 
       options={{ title: 'Signin' }}
      />
    </Stack.Navigator>     
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <StackRnRoutes />
    </NavigationContainer>
  );
}

Create User Registration Screen

Set the state with user auth state properties, create a form and bind with the onTextChange method. This method sets up the state for the individual form element. The addUser function uses the create user with email and password method to make the user registration functionality.

Update code in components/SignupScreen.js file.

import React, { Component } from 'react';
import firebase from '../config/firebase';
import { Button, Alert, StyleSheet, Text, View, TextInput, ActivityIndicator } from 'react-native';


class SignupScreen extends Component {

  constructor() {
    super();
    this.state = { 
      displayName: '',
      email: '', 
      password: '',
      isLoading: false
    }
  }

  onTextChange = (val, prop) => {
    const state = this.state;
    state[prop] = val;
    this.setState(state);
  }

  addUser = () => {
    if(this.state.email === '' && this.state.password === '') {
      Alert.alert('Enter correct details.')
    } else {
      this.setState({
        isLoading: true,
      })
      firebase
      .auth()
      .createUserWithEmailAndPassword(this.state.email, this.state.password)
      .then((res) => {
        res.user.updateProfile({
          displayName: this.state.displayName
        })
        console.log('User account created.')
        this.setState({
          isLoading: false,
          displayName: '',
          email: '', 
          password: ''
        })
        this.props.navigation.navigate('SigninScreen')
      })
      .catch(error => this.setState({ errorMessage: error.message }))
    }
  }

  render() {
    if(this.state.isLoading){
      return(
        <View style={styles.loading}>
          <ActivityIndicator size="large" color="grey"/>
        </View>
      )
    }    
    return (
      <View style={styles.formWrapper}>  
        <TextInput
          style={styles.formField}
          placeholder="Name"
          value={this.state.displayName}
          onChangeText={(val) => this.onTextChange(val, 'displayName')}
        />      
        <TextInput
          style={styles.formField}
          placeholder="Email"
          value={this.state.email}
          onChangeText={(val) => this.onTextChange(val, 'email')}
        />
        <TextInput
          style={styles.formField}
          placeholder="Password"
          value={this.state.password}
          onChangeText={(val) => this.onTextChange(val, 'password')}
          maxLength={20}
          secureTextEntry={true}
        />   

        <Button
          color="blue"
          title="Signup"
          onPress={() => this.addUser()}
        />        

        <Text 
          style={styles.redirectText}
          onPress={() => this.props.navigation.navigate('SigninScreen')}>
          Already have account ? Signin
        </Text>                          
      </View> 
    );
  }
}

const styles = StyleSheet.create({
  formWrapper: {
    flex: 1,
    display: "flex",
    justifyContent: "center",
    padding: 30,
    backgroundColor: '#fff',    
    flexDirection: "column",
  },
  formField: {
    width: '100%',
    alignSelf: "center",
    borderColor: "#444",
    borderBottomWidth: 1,    
    marginBottom: 20,
    paddingBottom: 20,
  },
  redirectText: {
    textAlign: 'center',
    color: 'blue',
    marginTop: 24,    
  },
  loading: {
    position: 'absolute',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'white',    
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
  }
});

export default SignupScreen;

Create Login Auth Screen

In this step, you require to use the signInWithEmailAndPassword() method to login the user with email and password.

Update code in components/SigninScreen.js file.

import React, { Component } from 'react';
import firebase from '../config/firebase';
import { Button, Alert, StyleSheet, Text, View, TextInput, ActivityIndicator } from 'react-native';


class SigninScreen extends Component {
  constructor() {
    super();
    this.state = { 
      email: '', 
      password: '',
      isLoading: false
    }
  }

  onTextChange = (val, prop) => {
    const state = this.state;
    state[prop] = val;
    this.setState(state);
  }

  signIn = () => {
    if(this.state.email === '' && this.state.password === '') {
      Alert.alert('Enter correct details.')
    } else {
      this.setState({
        isLoading: true,
      })
      firebase
      .signInWithEmailAndPassword(this.state.email, this.state.password)
      .then((res) => {
        this.setState({
          isLoading: false,
          email: '', 
          password: ''
        })
        alert('Logged in to app')
      })
      .catch(error => this.setState({ errorMessage: error.message }))
    }
  }

  render() {
    if(this.state.isLoading){
      return(
        <View style={styles.loading}>
          <ActivityIndicator size="large" color="grey"/>
        </View>
      )
    }    
    return (
      <View style={styles.formWrapper}> 
        <TextInput
          style={styles.formField}
          placeholder="Email"
          value={this.state.email}
          onChangeText={(val) => this.onTextChange(val, 'email')}
        />
        <TextInput
          style={styles.formField}
          placeholder="Password"
          value={this.state.password}
          onChangeText={(val) => this.onTextChange(val, 'password')}
          maxLength={20}
          secureTextEntry={true}
        />   
        <Button
          color="black"
          title="Login"
          onPress={() => this.signIn()}
        />

        <Text 
          style={styles.redirectText}
          onPress={() => this.props.navigation.navigate('SignupScreen')}>
          Don't have account ? Signup
        </Text>                          
      </View> 
    );
  }
}

const styles = StyleSheet.create({
  formWrapper: {
    flex: 1,
    display: "flex",
    justifyContent: "center",
    padding: 30,
    backgroundColor: '#fff',    
    flexDirection: "column",
  },
  formField: {
    width: '100%',
    alignSelf: "center",
    borderColor: "#444",
    borderBottomWidth: 1,    
    marginBottom: 20,
    paddingBottom: 20,
  },
  redirectText: {
    textAlign: 'center',
    color: 'blue',
    marginTop: 24,    
  },
  loading: {
    position: 'absolute',
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: 'white',    
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
  }
});

export default SigninScreen;

Run App in Device

Lastly, we need to run the app on the device; first, install the Expo Client on your smartphone.

You may get the expo client either from Google Play Store or App Store.

Run either of the suggested command.

# npm
npm start

# yarn
yarn start

Now, on your browser or terminal screen, you must be seeing a QR code, you have to scan that QR code through your expo app.

Wait for some time while your app is being compiled. Ensure that your development machine and smartphone are on the same network.

Summary

We will walk you through step by step and help you set up the react native app. Create and set up a new Firebase project, configure the Firebase authentication for user registration, and log in with email/password. Also, create and set up routing and navigation, create and register screens in react native. Eventually, React Native Firebase login and signup tutorial is completed.

Exit mobile version