Android

Introduction

As discussed in our previous posts, Firebase provides User Authentication in many types as Email, Google Plus, Facebook, Phone Authentication and more. We already have seen or heard about OTP authentication for mobile app users. In this article, we will learn a very useful feature of Firebase Phone Authentication.
To learn about Firebase Email authentication, read my posts here.
  1. Firebase User Authentication In Android - Part One
  2. Firebase User Authentication In Android - Part Two

Firebase Phone Authentication

Google's Firebase provides free service for a limited amount of authentication per month. However, if you need to sign in a very high volume of users with phone authentication, you might need to upgrade your pricing plan. You can view the pricing page here.
You can use Firebase Authentication to sign in a user by sending an SMS message to the user's phone. The user signs in using a one-time code contained in the SMS message.

Firebase Setup

Before starting to code, we have to set up Firebase for Android and enable Phone Authentication. If you are new to firebase, the following link will be useful to know the method for setting up the project in firebase.
https://androidmads.blogspot.in/2016/10/android-getting-started-with-firebase.html
After setting up, open Authentication sign-in method and enable the phone authentication method as shown in the following figure.
Android
You should add SHA Fingerprint in your application. The following terminal will be used to get the SHA Fingerprint with Command Prompt in Windows for debug mode.
  1. keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android
Coding Part
I have split this part into 3 steps as follows.
Step 1 - Creating a New Project with Android Studio
  1. Open Android Studio and select Create a new project.
  2. Name the project as you wish and select your activity template.
    Android
  3. Click the Finish button to create a new project in Android Studio.
Step 2- Setting up the Firebase Library
In this part, we will see how to set up the library for the project.
  1. Open your project level build.gradle file and add the following lines in dependencies
    1. {
    2. classpath 'com.google.gms:google-services:3.1.0'
    3. }
  1. Then add the following lines in all projects in the project level build.gradle file.
    1. allprojects {
    2. repositories {
    3. google()
    4. jcenter()
    5. maven {
    6. url "https://maven.google.com"
    7. }
    8. }
    9. }
  1. Then add the following lines in app level build.gradle file to apply google services to your project.
    1. dependencies {
    2. ...
    3. implementation 'com.google.firebase:firebase-auth:11.8.0'
    4. }
    5. apply plugin: 'com.google.gms.google-services'
  1. Then click “Sync Now” to setup your project.
Step 3 - Implementation of Firebase Phone Authentication
In this step, we will learn about, How to
Send Verification Code
Validates Authentication Success & Failure Manage Sign-In & Sign-Out
Full Code
You can find the full code implementation here.
  1. public class PhoneAuthActivity extends AppCompatActivity implements
  2. View.OnClickListener {
  3. EditText mPhoneNumberField, mVerificationField;
  4. Button mStartButton, mVerifyButton, mResendButton;
  5. private FirebaseAuth mAuth;
  6. private PhoneAuthProvider.ForceResendingToken mResendToken;
  7. private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks;
  8. String mVerificationId;
  9. private static final String TAG = "PhoneAuthActivity";
  10. @Override
  11. protected void onCreate(@Nullable Bundle savedInstanceState) {
  12. super.onCreate(savedInstanceState);
  13. setContentView(R.layout.activity_phone);
  14. mPhoneNumberField = (EditText) findViewById(R.id.field_phone_number);
  15. mVerificationField = (EditText) findViewById(R.id.field_verification_code);
  16. mStartButton = (Button) findViewById(R.id.button_start_verification);
  17. mVerifyButton = (Button) findViewById(R.id.button_verify_phone);
  18. mResendButton = (Button) findViewById(R.id.button_resend);
  19. mStartButton.setOnClickListener(this);
  20. mVerifyButton.setOnClickListener(this);
  21. mResendButton.setOnClickListener(this);
  22. mAuth = FirebaseAuth.getInstance();
  23. mCallbacks = new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
  24. @Override
  25. public void onVerificationCompleted(PhoneAuthCredential credential) {
  26. Log.d(TAG, "onVerificationCompleted:" + credential);
  27. signInWithPhoneAuthCredential(credential);
  28. }
  29. @Override
  30. public void onVerificationFailed(FirebaseException e) {
  31. Log.w(TAG, "onVerificationFailed", e);
  32. if (e instanceof FirebaseAuthInvalidCredentialsException) {
  33. mPhoneNumberField.setError("Invalid phone number.");
  34. } else if (e instanceof FirebaseTooManyRequestsException) {
  35. Snackbar.make(findViewById(android.R.id.content), "Quota exceeded.",
  36. Snackbar.LENGTH_SHORT).show();
  37. }
  38. }
  39. @Override
  40. public void onCodeSent(String verificationId,
  41. PhoneAuthProvider.ForceResendingToken token) {
  42. Log.d(TAG, "onCodeSent:" + verificationId);
  43. mVerificationId = verificationId;
  44. mResendToken = token;
  45. }
  46. };
  47. }
  48. private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
  49. mAuth.signInWithCredential(credential)
  50. .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
  51. @Override
  52. public void onComplete(@NonNull Task<AuthResult> task) {
  53. if (task.isSuccessful()) {
  54. Log.d(TAG, "signInWithCredential:success");
  55. FirebaseUser user = task.getResult().getUser();
  56. startActivity(new Intent(PhoneAuthActivity.this, MainActivity.class));
  57. finish();
  58. } else {
  59. Log.w(TAG, "signInWithCredential:failure", task.getException());
  60. if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
  61. mVerificationField.setError("Invalid code.");
  62. }
  63. }
  64. }
  65. });
  66. }
  67. private void startPhoneNumberVerification(String phoneNumber) {
  68. PhoneAuthProvider.getInstance().verifyPhoneNumber(
  69. phoneNumber, // Phone number to verify
  70. 60, // Timeout duration
  71. TimeUnit.SECONDS, // Unit of timeout
  72. this, // Activity (for callback binding)
  73. mCallbacks); // OnVerificationStateChangedCallbacks
  74. }
  75. private void verifyPhoneNumberWithCode(String verificationId, String code) {
  76. PhoneAuthCredential credential = PhoneAuthProvider.getCredential(verificationId, code);
  77. signInWithPhoneAuthCredential(credential);
  78. }
  79. private void resendVerificationCode(String phoneNumber,
  80. PhoneAuthProvider.ForceResendingToken token) {
  81. PhoneAuthProvider.getInstance().verifyPhoneNumber(
  82. phoneNumber, // Phone number to verify
  83. 60, // Timeout duration
  84. TimeUnit.SECONDS, // Unit of timeout
  85. this, // Activity (for callback binding)
  86. mCallbacks, // OnVerificationStateChangedCallbacks
  87. token); // ForceResendingToken from callbacks
  88. }
  89. private boolean validatePhoneNumber() {
  90. String phoneNumber = mPhoneNumberField.getText().toString();
  91. if (TextUtils.isEmpty(phoneNumber)) {
  92. mPhoneNumberField.setError("Invalid phone number.");
  93. return false;
  94. }
  95. return true;
  96. }
  97. @Override
  98. public void onStart() {
  99. super.onStart();
  100. FirebaseUser currentUser = mAuth.getCurrentUser();
  101. if (currentUser != null) {
  102. startActivity(new Intent(PhoneAuthActivity.this, MainActivity.class));
  103. finish();
  104. }
  105. }
  106. @Override
  107. public void onClick(View view) {
  108. switch (view.getId()) {
  109. case R.id.button_start_verification:
  110. if (!validatePhoneNumber()) {
  111. return;
  112. }
  113. startPhoneNumberVerification(mPhoneNumberField.getText().toString());
  114. break;
  115. case R.id.button_verify_phone:
  116. String code = mVerificationField.getText().toString();
  117. if (TextUtils.isEmpty(code)) {
  118. mVerificationField.setError("Cannot be empty.");
  119. return;
  120. }
  121. verifyPhoneNumberWithCode(mVerificationId, code);
  122. break;
  123. case R.id.button_resend:
  124. resendVerificationCode(mPhoneNumberField.getText().toString(), mResendToken);
  125. break;
  126. }
  127. }
  128. }
Download Code
You can download the full source code of the article in GitHub. If you like this article, do star the repo in GitHub. Hit like the article.