Showing posts with label authentication. Show all posts
Showing posts with label authentication. Show all posts

Thursday, 17 February 2022

 

How to implement Phone Verification (OTP Verification) using Firebase Authentication in your Android App (in brief)

1. Create a project in Android Studio.

2. Go Firebase Console, open a firebase account.

3. Sign-in & Add your Android Project to Firebase using package name.

4. Go to Preject Settings>General tab page from the left pane of the firebase console. From here, download the google-services.json. Put this file under the app root folder of your Android Studio project.

5. Now, in your android project add dependency for Firebase Authentication in module level (app level) build gradle file.

   dependencies {

            implementation platform(‘com.google.firebase:firebase-bom:29.1.0’)

            //declare dependencies for Firebase authentication library

            //no need to specify version number if firebase bom is used

            implementation ‘com.google.firebase:firebase-auth’

}

No need to put firebase-auth library version as firebase-bom version is mentioned.

6. Set app’s SHA-1, SHA-256 hash in firebase console. To do so, go to authentication tool from left pane of the project’s firebase console.

To get the SHA-1 & SHA-256 of the Android app, go to signing report from Gradle (right pane of the Android Studio) ->Android->task

7. To enable phone number signing in (OTP verification) for your android app go to Firebase Console à Authentication section.

From the sign-in method page enable Phone number sign-in method.

8. Enable app verification.

To enable app verification, do so through safetyNet , i) enable Android DeviceCheck API from Google Cloud Console. The default firebase API key will be used.

Ii) If SHA-256 is not added, do so from setting page of the firebase console.

Now, we can implement phone verification in our android app.

A. To implements phone verification first create an UI to accept users phone number in our Android Studio platform.

B. Pass this phone number along with other options to request to firebase to verify the phone number through the following method-

PhoneAuthOptions options =
  PhoneAuthOptions.newBuilder(mAuth)
      .setPhoneNumber(phoneNumber)       // Phone number to verify
      .setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
      .setActivity(this)                 // Activity (for callback binding)
      .setCallbacks(mCallbacks)          // OnVerificationStateChangedCallbacks
      .build();
  PhoneAuthProvider.verifyPhoneNumber(options);    

 

mAuth is an instance of FirebaseAuth class. Get mAuth in the way following,

FirebaseAuth mAuth = FirebaseAuth.getInstance();

FirebaseAuth instance is created depending upon the google-services.json settings file we downloaded in step 4 and saved it in the app root folder of the project.

C. The callback used in firebase phone verification is an instance of OnVerificationStateChangedCallbacks. So, implement it in your Activity.

mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {

    @Override
    public void onVerificationCompleted(PhoneAuthCredential credential) {
        // This callback will be invoked in two situations:
        // 1 - Instant verification. In some cases the phone number can be instantly
        //     verified without needing to send or enter a verification code.
        // 2 - Auto-retrieval. On some devices Google Play services can automatically
        //     detect the incoming verification SMS and perform verification without
        //     user action.
        Log.d(TAG, "onVerificationCompleted:" + credential);

        signInWithPhoneAuthCredential(credential);
    }

    @Override
    public void onVerificationFailed(FirebaseException e) {
        // This callback is invoked in an invalid request for verification is made,
        // for instance if the the phone number format is not valid.
        Log.w(TAG, "onVerificationFailed", e);

        if (e instanceof FirebaseAuthInvalidCredentialsException) {
            // Invalid request
        } else if (e instanceof FirebaseTooManyRequestsException) {
            // The SMS quota for the project has been exceeded
        }

        // Show a message and update the UI
    }

    @Override
    public void onCodeSent(@NonNull String verificationId,
                           @NonNull PhoneAuthProvider.ForceResendingToken token) {
        // The SMS verification code has been sent to the provided phone number, we
        // now need to ask the user to enter the code and then construct a credential
        // by combining the code with a verification ID.
        Log.d(TAG, "onCodeSent:" + verificationId);

        // Save verification ID and resending token so we can use them later
        mVerificationId = verificationId;
        mResendToken = token;
    }
};

 

 

D. After the user entering the phone number and click to pass the data to firebase through the verification method, the firebase will send a verification code to the user’s phone.

E. Create UI to accept the verification code (OTP).

F. The app will get a verification ID (not OTP) once when the data is sent to firebase through its verification method (look at the onCodeSent() method of the callback). We need to create a PhoneAuthCredential Object using this verificationID and the verification code (OTP) that user will receive in his/her phone.

PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);

 

G. Now the user can be signed in with the credential through the following FirebaseAuth.signInWithCredential method.

private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
    mAuth.signInWithCredential(credential)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        // Sign in success, update UI with the signed-in user's information
                        Log.d(TAG, "signInWithCredential:success");

                        FirebaseUser user = task.getResult().getUser();
                        // Update UI
                    } else {
                        // Sign in failed, display a message and update the UI
                        Log.w(TAG, "signInWithCredential:failure", task.getException());
                        if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
                            // The verification code entered was invalid
                        }
                    }
                }
            });
}

 

The FirebaseUser object  that we get from the above signInWithPhoneCredential() method holds all related information of the FirebaseUser client.