Logging in a mobile app using the Phone number and a unique SMS verification code is one of the most common patterns to authenticate a user. In this tutorial, I am going to guide you through the process by demonstrating a login screen. To efficiently set up a backend service, let us use Firebase.

There is a particular flow is followed when it comes to using the Phone sign-in method. When the user enters a number, they are sending a request an OTP from Firebase. The Firebase service then uses reCAPTCHA first to verify the user’s authenticity. Once that’s confirmed, it sends the OTP to the mobile number user previously entered. Lastly, the user can enter that value to sign in successfully.

Phone Authentication Firebase React Native

Do note that I’m going to use an iOS simulator for this tutorial. So any library (such as react-native-firebase) that needs configuration set up to be platform-specific, please refer to their official docs.

Installing react-native-firebase

To get started, the first dependency our demo app requires is the react-native-fireabase which is recommended by the Firebase team to work with when using Firebase SDK in React Native apps.

# create a new project
react-native init rnFirebasePhoneAuth

cd rnFirebasePhoneAuth
# install the dependency
yarn add react-native-firebase

Next, only for iOS devices and simulators, navigate to ios/Podfile and enter the following lines:

pod 'Firebase/Core', '~> 6.3.0'
pod 'Firebase/Auth', '~> 6.3.0'

Then go back to the terminal window and execute the command below:

cd ios/
pod install

Create a Firebase Project

To get started, you’re going to need a Firebase app. Once you’ve created a new account with Firebase and logged in, create a new project by clicking on the New Project button.

react native sms authentication

Next, add the details regarding this new Firebase project.

firebase react native

Click the button Create project and you’ll be redirected to the dashboard screen. On the left side menu, click the settings icon, and then go to Project Settings.

firebase react native phone

From there, click on the button Add app, select the appropriate platform, and follow the included instructions.

add app firebase

Download the file GoogleService-info.plist if your selected platform in the previous step is iOS. Then, open Xcode adds this file to the project.

firebase xcode

For Android users, you will download google-services.json and save it at the location android/app/.

After adding the config file, you’ll have to follow the react-native-firebase documentation instructions here.

Using Phone Auth as a sign-in method

From Firebase services, to use phone authentication as the sign-in method, you are going to enable the service from your Firebase project.

In the Firebase console, go to Authentication > Sign-in method tab. There, enable the phone authentication method as shown in the image below.

This React Native app will be using reCAPTCHA verification to verify a user. You have to set this up manually. Open the file [PROJECT_NAME]/ios/[PROJECT_NAME].xworkspace in Xcode and then double-click the project name in the left tree view and select the app from the TARGETS section. Then select the Info tab, and expand the URL Types section.

Click the + button, and add a URL scheme for your reversed client ID. To find this value, open the GoogleService-Info.plist configuration file, and look for the REVERSED_CLIENT_ID key. Copy the value of that key and paste it into the URL Schemes box on the configuration page. Leave the other fields blank.

That is all required to configure the Firebase Phone auth service.

Create PhoneAuth component

Create a new file inside screens/PhoneAuth.js and let us first import all the necessary modules.

import React, { Component } from 'react'
import {
  StyleSheet,
  SafeAreaView,
  TouchableOpacity,
  View,
  Text,
  TextInput
} from 'react-native'
import firebase from 'react-native-firebase'

The class component PhoneAuth is going to have an initial state object to track four important values when a user enters their phone number.

  • phone: User’s phone number.
  • verificationCode: OTP code sent by Firebase via SMS (by default).
  • confirmResult: When the verification code is received, Firebase provides a parameter confirmResult that you can manually save to confirm the code and proceed further.
  • userId: The unique identifier created by Firebase when a new user registers with the app.
class PhoneAuth extends Component {
 state = {
 phone: '',
 confirmResult: null,
 verificationCode: '',
 userId: ''
 }

 validatePhoneNumber = () => {
 var regexp = /^\+[0-9]?()[0-9](\s|\S)(\d[0-9]{8,16})$/
 return regexp.test(this.state.phone)
 }

 // ... rest of the code
 render() {
 return(
 // ...
 )
 }
}

export default PhoneAuth

In the above snippet, there is a helper method called validatePhoneNumber() to verify that a user is entering a valid phone number or not. You can use a RegExp pattern. If the phone number entered by the user in the input field matches the RegExp pattern, it returns a boolean true.

Adding a handler to send the OTP

The validation of the user’s phone number is going to be the first method invoked inside the handler method that enables the Firebase to send the OTP (“one time password”) based on the user’s input.

Create a handler method handleSendCode. Inside this method, firebase.auth().signInWithPhoneNumber() is used to when the phone validatation returns true and the user receives a confirmation code. When the promise gets resolved, it will update the state variable confirmResult.

handleSendCode = () => {
  // Request to send OTP
  if (this.validatePhoneNumber()) {
    firebase
      .auth()
      .signInWithPhoneNumber(this.state.phone)
      .then(confirmResult => {
        this.setState({ confirmResult })
      })
      .catch(error => {
        alert(error.message)

        console.log(error)
      })
  } else {
    alert('Invalid Phone Number')
  }
}

Adding a confirmation view

Let us add another view for when the user receives the verification code. At this point, the app will display two input fields.

The first input field is for the user to change their phone number if there’s been a mistake. Otherwise, the phone number is displayed on the initial screen and the user has to enter the OTP in the second input field.

Add a new method changePhoneNumber that is going to take care of incorrect phone numbers.

changePhoneNumber = () => {
  this.setState({ confirmResult: null, verificationCode: '' })
}

The handler method handleVerifyCode is going to send the request back to Firebase to verify the OTP entered by the user. If the OTP verification is a success, for now, you can display the user’s uid in an alert message.

handleVerifyCode = () => {
  // Request for OTP verification
  const { confirmResult, verificationCode } = this.state
  if (verificationCode.length == 6) {
    confirmResult
      .confirm(verificationCode)
      .then(user => {
        this.setState({ userId: user.uid })
        alert(`Verified! ${user.uid}`)
      })
      .catch(error => {
        alert(error.message)
        console.log(error)
      })
  } else {
    alert('Please enter a 6 digit OTP code.')
  }
}

The following snippet, renderConfirmationCodeView is only going to be displayed when the value of confirmResult is true.

renderConfirmationCodeView = () => {
  return (
    <View style={styles.verificationView}>
      <TextInput
        style={styles.textInput}
        placeholder='Verification code'
        placeholderTextColor='#eee'
        value={this.state.verificationCode}
        keyboardType='numeric'
        onChangeText={verificationCode => {
          this.setState({ verificationCode })
        }}
        maxLength={6}
      />
      <TouchableOpacity
        style={[styles.themeButton, { marginTop: 20 }]}
        onPress={this.handleVerifyCode}>
        <Text style={styles.themeButtonTitle}>Verify Code</Text>
      </TouchableOpacity>
    </View>
  )
}

Here is the code snippet for the complete JSX inside the render() method:

return (
  <SafeAreaView style={[styles.container, { backgroundColor: '#333' }]}>
    <View style={styles.page}>
      <TextInput
        style={styles.textInput}
        placeholder='Phone Number with country code'
        placeholderTextColor='#eee'
        keyboardType='phone-pad'
        value={this.state.phone}
        onChangeText={phone => {
          this.setState({ phone })
        }}
        maxLength={15}
        editable={this.state.confirmResult ? false : true}
      />

      <TouchableOpacity
        style={[styles.themeButton, { marginTop: 20 }]}
        onPress={
          this.state.confirmResult
            ? this.changePhoneNumber
            : this.handleSendCode
        }>
        <Text style={styles.themeButtonTitle}>
          {this.state.confirmResult ? 'Change Phone Number' : 'Send Code'}
        </Text>
      </TouchableOpacity>

      {this.state.confirmResult ? this.renderConfirmationCodeView() : null}
    </View>
  </SafeAreaView>
)

Lastly, let us add some styles to the demo app.

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#aaa'
  },
  page: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center'
  },
  textInput: {
    marginTop: 20,
    width: '90%',
    height: 40,
    borderColor: '#555',
    borderWidth: 2,
    borderRadius: 5,
    paddingLeft: 10,
    color: '#fff',
    fontSize: 16
  },
  themeButton: {
    width: '90%',
    height: 50,
    alignItems: 'center',
    justifyContent: 'center',
    backgroundColor: '#888',
    borderColor: '#555',
    borderWidth: 2,
    borderRadius: 5
  },
  themeButtonTitle: {
    fontSize: 24,
    fontWeight: 'bold',
    color: '#fff'
  },
  verificationView: {
    width: '100%',
    alignItems: 'center',
    marginTop: 50
  }
})

Run the demo app

I am using an iOS simulator to demonstrate the app. You are going to get similar results as well. Initially, the user will be welcomed by the following screen. To test it out, enter a valid phone number.

On clicking the button Send code, the reCAPTCHA process will trigger if the user is signing in for the first time.

firebase auth sms

After that, the user receives the verification code via SMS.

firebase react native OTP

Enter the verification code.

login sms firebase mobile

On success, it responds with a uid in an alert message that you can verify in the Firebase console.

mobile firebase otp

That’s it. This is how you set up Firebase Phone Authentication in React Native. We are using this flow in all of our React Native templates, so you can save a lot of time by downloading one of our free React Native templates.

Next Steps


Leave a Reply

Your email address will not be published. Required fields are marked *

Shopping Cart