How to implement phone number Verification by OTP using Firebase in Android

Introduction

Hey guys!  In this tutorial, I am covering user verification by phone number by sending OTP to the mobile using Firebase authentication.

You can use Firebase Authentication to enable a user to sign in to your app by sending an SMS to user’s device which contains a one-time-password. The user then enters this OTP in your app, if the OTP matches then sign in is successful and the user can then access your app.

In the last tutorial, you learned about user verification using Facebook account kit.

Firebase Authentication

Firebase is a Google product which provides backend services, SDKs, and ready-made UI libraries to authenticate users to your app. It supports authentication using passwords, phone numbers, popular federated identity providers like Google, Facebook and Twitter, and more.

You may authenticate users of your app either by using Firebase UI which provides a complete user interface for sign in and authentication or you can integrate Firebase SDK manually into your app.

What you should already KNOW

To understand this tutorial you should be familiar with:

  • Basic knowledge of JAVA and Android.

What you should have

To make this app you should have:

  • The latest version of Android Studio Installed on your PC or Laptop.
  • A smartphone, as OTP cannot be sent to an emulator.
  • A Gmail ID to enable Firebase and add your project to Firebase console.

What you will learn

In this tutorial you will learn:

  • Setting up a new Android Studio project.
  • Integrating Firebase to your project.
  • Creating simple XML layout for your app.
  • Sending and verifying OTP using Firebase in Android JAVA code.

What you will do

In the process of making this app you will:

  • Create an app and add user interface elements such as Buttons, Edit texts, and Text views.
  • Add your project to Firebase console and enable phone authentication.
  • Implement click listeners on buttons to sign in (Generate OTP) and sign out.
  • Call Firebase authentication methods on the button on click events.
  • Retrieve user mobile number from firebase user data.

App overview

The “OTP Authentication” app will consist of two Activities  MainActivity and SignedIn. MainActivity activity will have two edit texts, one for the phone number and the other for received OTP, Also it will have two buttons, one to generate OTP and other to verify OTP. If the OTP match is successful then it will open SignedIn activity via Intent. If the OTP does not match then it will pop a toast message, “Incorrect OTP”.

SignedIn activity will include a text view displaying number and a sign out button on click of which app sign-outs and go back to MainActivity activity.

Here’s what the finished app will look like:

Note: Due to security issues the complete mobile number is not entered in the above video example.

Setting up the project

STEP1: SET UP A NEW ANDROID PROJECT

  • Start Android Studio and Click on “new project”.
  • Give your application a name, mine is “OTP Authentication”.
  • click next and choose Target android device.
  • next, choose an empty activity to keep things simple.
  • next, name your Activity and click finish to build the project.

STEP2: Add Firebase to your app

  • Goto Firebase Console
  • Login with your Gmail ID
  • On the welcome screen of Firebase click on Add project.
  • Add project window will open, there enter your project name and select your country, Project id will be automatically created and then click on CREATE PROJECT button.
  • After this, your app’s dashboard will open. click on Add Firebase to your Android app.
  • Now you have to register your app by providing the app package name and SHA-1 signing certificate on below screen.
  • To find the App package name open AndroidManifest.xml and on the top, there is the package name
  • To get the SHA-1 signing certificate, click on Gradle tab on the right end of Android studio to open Gradle properties> then click on :app> android> double click on signingReport. In the Monitor pane, you will see SHA1.
  • Copy and paste the package name and the SHA1 signing certificate in the firebase console register page. Then, click on REGISTER APP button.
  • Now you have to download the google-services.json file from the download config page and paste it in app module.
  • After than in project pane, click on Gradle Scripts> open project level build.gradle file and add google service dependency in buildscript.
    classpath 'com.google.gms:google-services:3.2.0'

  • open app level build.gradle add firebase dependency along with firebase authentication dependency.
    implementation 'com.google.firebase:firebase-core:11.8.0'
    implementation 'com.google.firebase:firebase-auth:11.8.0'
    
    note, for android studio below 3.0.1 use compile instead of implementation.

    and add the plugin for google service at the bottom of the file.

    apply plugin: 'com.google.gms.google-services'
    
    

  • Click on Sync Now and let the Gradle build.
  • Now go back to Firebase console and click on Project Overview. In Discover Firebase section there is a card named Authentication, click on GET STARTED on Authentication card.
  • On the next page click on SETUP SIGN-IN METHOD and enable phone authentication, then SAVE it. At this point, we are done with the initial setup.

step3: EDIT androidmanifest.XML

Our application needs internet for sending OTP.  So, for this reason, we have to, first of all, give permission to our app to use the internet. Add the following line to your AndroidManifest.xml inside manifest tag.

<uses-permission android:name=“android.permission.INTERNET”/>

DESIGN LAYOUT OF THE APP

step1: Configure colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#5bb4b4</color>
    <color name="colorPrimaryDark">#308e9f</color>
    <color name="colorAccent">#7fbcf5</color>
    <color name="textColor">#292929</color>
</resources>

step2: Specify strings.xml

<resources>
    <string name="app_name">OTPAuthentication</string>
    <string name="phone_number">Phone Number</string>
    <string name="generate_otp">Generate OTP</string>
    <string name="enter_otp">Enter OTP</string>
    <string name="verify_sign_in">Verify and Sign In</string>
    <string name="sign_out">sign out</string>
</resources>

step3: Design interface of Main Activity

The MainActivity is our first screen. It will consist of two edit texts for the phone number and OTP and two buttons to generate OTP and verify OTP respectively.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.tutorial.lws.otpauthentication.MainActivity">

    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/et_phone_number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/phone_number"
        android:textColor="@color/textColor"
        android:layout_margin="20dp"/>

    <android.support.v7.widget.AppCompatEditText
        android:id="@+id/et_otp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/enter_otp"
        android:clickable="false"
        android:textColor="@color/textColor"
        android:layout_margin="20dp"/>

    <Button
        android:id="@+id/btn_generate_otp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/generate_otp"
        android:background="@color/colorAccent"
        android:textColor="@color/textColor"
        android:layout_margin="20dp"/>
    <Button
        android:id="@+id/btn_sign_in"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/verify_sign_in"
        android:background="@color/colorAccent"
        android:textColor="@color/textColor"
        android:layout_margin="20dp"/>

</LinearLayout>

Our App will look like this when you run it on the device.

step4: CREATE A NEW ACTIVITY SignedIn activity

  • Right click on the app
  • click on New>Activity>Empty Activity
  • Name the name it as SignedIn activity.
  • click finish.

step5: Design interface of SignedIn Activity

The SignedIn activity is our second screen which would open on successful OTP verification. It will consist of one text view to display user’s mobile number and one sign out button.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.tutorial.lws.otpauthentication.SignedIn">

    <TextView
        android:id="@+id/tv_phone_number"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_margin="20dp"/>
    
    <Button
        android:id="@+id/btn_sign_out"
        android:layout_centerInParent="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/verify_sign_in"
        android:background="@color/colorAccent"
        android:textColor="@color/textColor"
        android:layout_margin="20dp"/>
    
</RelativeLayout>

The second screen will look like this initially

JAVA CODE TO SIGN-IN VIA OTP

STEP1: LINK XML BUTTONS and Edittexts TO JAVA in Main Activity

First of all, we will declare global variables for Buttons and EditTexts.

Button btnGenerateOTP, btnSignIn;

EditText etPhoneNumber, etOTP;

After then, we will create a findViews() method in MainActivity.java.
In this, we will link the Buttons and edittexts that we declare in java to buttons and edittexts in activity_main.xml. Then we will call this method in activities onCreate() method.

private void findViews() {
    btnGenerateOTP=findViewById(R.id.btn_generate_otp);
    btnSignIn=findViewById(R.id.btn_sign_in);

    etPhoneNumber=findViewById(R.id.et_phone_number);
    etOTP=findViewById(R.id.et_otp);
}

step2: Declare Phone number and OTP variables

Declare String type global variables to store phone number and OTP from EditTexts.

String phoneNumber, otp;

step3: Implement onCLickListener to Generate OTP  button  to send SMS

In the MainActivity’s onCreate() method we will set click listener to btnGenerateOTP in which we will get the text from phone number EditText and store it in phoneNumber variable. Then we will initiate the sign-in flow by passing this phone number variable to PhoneAuthProvider.getInstance().verifyPhoneNumber method to request firebase to verify the user’s phone number.

Declare another global variable for verification state change call back that we have to pass as a parameter.

PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallback;
btnGenerateOTP.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        phoneNumber=etPhoneNumber.getText().toString();

        PhoneAuthProvider.getInstance().verifyPhoneNumber(
                phoneNumber,                     // Phone number to verify
                60,                           // Timeout duration
                TimeUnit.SECONDS,                // Unit of timeout
                MainActivity.this,        // Activity (for callback binding)
                mCallback);                      // OnVerificationStateChangedCallbacks
    }
});

Above method will send an SMS to the provided phone number. As verifyPhoneNumber() is reentrant, it will not send another SMS on button click until the original request is timed out.

step4: Handle callback functions

Next, we have to handle the result of the request initiated on button’s click. For this, we have to create a new instance of PhoneAuthProvider.OnVerificationStateChangedCallbacks().
In the methods of this call back we will update the user with the result via Toast message.

Create global variables.

FirebaseAuth auth;
private String verificationCode;

Then, make a function StartFirebaseLogin() to handle the result of callbacks. Call this function in onCreate method.

private void StartFirebaseLogin() {
 
    auth = FirebaseAuth.getInstance();
    mCallback = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
        
        @Override
        public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
            Toast.makeText(MainActivity.this,"verification completed",Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onVerificationFailed(FirebaseException e) {
            Toast.makeText(MainActivity.this,"verification fialed",Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
            super.onCodeSent(s, forceResendingToken);
            verificationCode = s;
            Toast.makeText(MainActivity.this,"Code sent",Toast.LENGTH_SHORT).show();
        }
    };
}

After completing this step, OTP code will be sent to your device. Enter your mobile number and click generate OTP button. After that, the user will enter the OTP received via SMS and start the verification process.

step5: Implement onCLickListener to sign in button to verify OTP

Next, we will implement click listener on btnSignIn which will get the OTP from EditText and initiate the verification process. To begin with,  create a PhoneAuthCredential object with the verification code and OTP as parameters. further, call SigninWithPhone() with credential as a parameter to complete sign-in.

btnSignIn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        otp=etOTP.getText().toString();
        PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationCode, otp)
       SigninWithPhone(credential);
    }
});

Afterward, follow next step.

step6: Sign in the user

Finally, this is the last step of the sign-in process. To this end, we will make SigninWithPhone() method. If the verification is successful then we will open SignedIn Activity. Otherwise, a toast message will be printed to show the error message.

private void SigninWithPhone(PhoneAuthCredential credential) {
    auth.signInWithCredential(credential)
            .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        startActivity(new Intent(MainActivity.this,SignedIn.class));
                        finish();
                    } else {
                        Toast.makeText(MainActivity.this,"Incorrect OTP",Toast.LENGTH_SHORT).show();
                    }
                }
            });
}

Complete MainActivity.java

package com.tutorial.lws.otpauthentication;

import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.FirebaseException;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.PhoneAuthCredential;
import com.google.firebase.auth.PhoneAuthProvider;

import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

    Button btnGenerateOTP, btnSignIn;

    EditText etPhoneNumber, etOTP;

    String phoneNumber, otp;
    
    FirebaseAuth auth;

    PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallback;
    private String verificationCode;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViews();

        StartFirebaseLogin();

        btnGenerateOTP.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                phoneNumber=etPhoneNumber.getText().toString();

                PhoneAuthProvider.getInstance().verifyPhoneNumber(
                        phoneNumber,                     // Phone number to verify
                        60,                           // Timeout duration
                        TimeUnit.SECONDS,                // Unit of timeout
                        MainActivity.this,        // Activity (for callback binding)
                        mCallback);                      // OnVerificationStateChangedCallbacks
            }
        });

        btnSignIn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                otp=etOTP.getText().toString();

                PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationCode, otp);

                SigninWithPhone(credential);
            }
        });
    }

    private void SigninWithPhone(PhoneAuthCredential credential) {
        auth.signInWithCredential(credential)
                .addOnCompleteListener(new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            startActivity(new Intent(MainActivity.this,SignedIn.class));
                            finish();
                        } else {
                            Toast.makeText(MainActivity.this,"Incorrect OTP",Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }

    private void findViews() {
        btnGenerateOTP=findViewById(R.id.btn_generate_otp);
        btnSignIn=findViewById(R.id.btn_sign_in);

        etPhoneNumber=findViewById(R.id.et_phone_number);
        etOTP=findViewById(R.id.et_otp);
    }

    private void StartFirebaseLogin() {

        auth = FirebaseAuth.getInstance();
        mCallback = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

            @Override
            public void onVerificationCompleted(PhoneAuthCredential phoneAuthCredential) {
                Toast.makeText(MainActivity.this,"verification completed",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onVerificationFailed(FirebaseException e) {
                Toast.makeText(MainActivity.this,"verification fialed",Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCodeSent(String s, PhoneAuthProvider.ForceResendingToken forceResendingToken) {
                super.onCodeSent(s, forceResendingToken);
                verificationCode = s;
                Toast.makeText(MainActivity.this,"Code sent",Toast.LENGTH_SHORT).show();
            }
        };
    }


}

JAVA CODE TO SIGN OUT

step1: LINK XML BUTTONS and Edittexts TO JAVA in SignedIn Activity

Likewise the MainActivity we will declare global variables for Textview and sign out button.

TextView tvPhoneNumber;
Button btnSignOut;

Moreover, we will find the xml views in SignedIn.java

private void findViews() {
    tvPhoneNumber=findViewById(R.id.tv_phone_number);
    btnSignOut=findViewById(R.id.btn_sign_out);
}

Next, we will get phone number from firebase and set it in the textview.

private void setPhoneNumber(){
    FirebaseUser user= FirebaseAuth.getInstance().getCurrentUser();
    try {
        tvPhoneNumber.setText(user.getPhoneNumber());
    }catch (Exception e){
        Toast.makeText(this,"Phone number not found",Toast.LENGTH_SHORT).show();
    }
}

Finally, set click listener on btnSignOut to sign-out from the app and return to MainActivity

btnSignOut.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        FirebaseAuth.getInstance().signOut();
        startActivity(new Intent(SignedIn.this,MainActivity.class));
        finish();
    }
});

complete SignedIn.java

package com.tutorial.lws.otpauthentication;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;

public class SignedIn extends AppCompatActivity {

    TextView tvPhoneNumber;
    Button btnSignOut;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_signed_in);

        findViews();

       setPhoneNumber();

       btnSignOut.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               FirebaseAuth.getInstance().signOut();
               startActivity(new Intent(SignedIn.this,MainActivity.class));
               finish();
           }
       });
    }

    private void findViews() {
        tvPhoneNumber=findViewById(R.id.tv_phone_number);
        btnSignOut=findViewById(R.id.btn_sign_out);
    }

    private void setPhoneNumber(){
        FirebaseUser user= FirebaseAuth.getInstance().getCurrentUser();
        try {
            tvPhoneNumber.setText(user.getPhoneNumber());
        }catch (Exception e){
            Toast.makeText(this,"Phone number not found",Toast.LENGTH_SHORT).show();
        }
    }
}

Summing-up

In this tutorial, you learned about the firebase authentication to verify the user of your app via SMS OTP and get user’s phone number from firebase user data.

If you liked this post, I’d be very grateful if you’d help it spread, sharing it on Twitter, Facebook or LinkedIn. Please feel free to share your views in the comment box. Thank you!

Latest posts by Rahul Huria (see all)

22 thoughts on “How to implement phone number Verification by OTP using Firebase in Android”

  1. hello tarun,
    I am always getting the callback of verification failed….even after doing all the correct steps..pls help

    Reply
  2. @Override
    public void onVerificationFailed(FirebaseException e) {
    Toast.makeText(MainActivity.this,”verification fialed”,Toast.LENGTH_SHORT).show();
    }
    always landing into this code…

    Reply
  3. i recently run above the code. and its work not properly. when i run in my android phone. shown me sign in page. and after that i write phone number and click generate OTP button. that time my code will be executed in verification failed.
    please Help me.

    Reply
  4. Good information. Lucky me I recently found your blog by chance (stumbleupon).
    I have saved as a favorite for later!

    Reply
  5. Your mode of describing the whole thing in this post is genuinely nice, every one be able to easily know it, Thanks a lot.|

    Reply

Leave a Comment