Hello Android Lovers. Let’s see how the Android OTP verification works in Android Development using Firebase. In here I am going to design two screens. Phone number Enter screen and OTP verification screen. Let’s design those screens first.
Design 01 – Phone Number Enter Screen

In here, I am getting Full name, Phone number and the Country code. Because I am going to Register a new User by his /her phone number. Just forget the Full name. Let’s continue with phone number and country code.
Let’s see the design code.
<?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"
android:padding="30dp"
tools:context=".common.RegPhoneActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<ImageView
android:id="@+id/back_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/general_back_icon" />
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginTop="30dp"
android:layout_gravity="center"
android:src="@drawable/logo" />
<TextView
android:id="@+id/createAccountTitle"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="SIGN UP WITH PHONE"
android:textAlignment="center"
android:fontFamily="@font/muli_black"
android:textColor="#ffffff"
android:textSize="15sp"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<com.hbb20.CountryCodePicker
android:id="@+id/country_code_picker"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@drawable/black_border"
android:padding="7dp"
app:ccp_autoDetectCountry="true"
app:ccp_showFlag="true"
app:ccp_showFullName="true"
app:ccp_showNameCode="true" />
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/create_account_phone_number"
style="@style/Widget.MaterialComponents.TextInputLayout.FilledBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:hint="Enter Phone Number"
android:textColorHint="@color/black"
app:boxBackgroundColor="#ffffff"
app:boxStrokeColor="@color/black"
app:boxStrokeWidthFocused="2dp"
app:endIconMode="clear_text"
app:endIconTint="@color/black"
app:hintTextColor="#000000"
app:startIconDrawable="@drawable/field_phone_number_icon"
app:startIconTint="@color/black">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fontFamily="@font/muli_semibold"
android:inputType="phone"
android:textColor="#000000"
android:textCursorDrawable="@null" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:id="@+id/createAccountNextBtn"
android:background="@drawable/button_background"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:layout_marginTop="30dp"
android:layout_marginBottom="20dp"
android:textColor="#FFFFFF"
android:text="NEXT"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
I remove the full name XML code. “TextInputLayout” is for the phone number text field and “CountryCodePicker” is for get the country code. It is a dependency. Copy this below code and paste it in the build.gradle(app) file.
//country code picker
implementation 'com.hbb20:ccp:2.3.1'
After that go to manifest file. Copy this below code and paste it in the top of <application> tag.
<uses-permission android:name="android.permission.INTERNET" />
Because we need internet access to get the OTP code and use your own background drawable file. Like orange background in my one.
Design 02 – OTP Verification Screen | Android OTP verification using firebase

Let’s go to the code.
<?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"
android:padding="30dp"
tools:context=".common.verificationActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/back_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:src="@drawable/general_back_icon" />
<ImageView
android:id="@+id/forget_password_icon"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:src="@drawable/verification_icon" />
<TextView
android:id="@+id/forget_password_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="36dp"
android:fontFamily="@font/muli_black"
android:gravity="center"
android:includeFontPadding="false"
android:text="VERIFICATION"
android:textAlignment="center"
android:textAllCaps="true"
android:textColor="#FFFFFF"
android:textSize="30sp" />
<TextView
android:id="@+id/forget_password_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="@font/muli"
android:gravity="center"
android:text="ENTER OTP CODE TO VERIFY YOUR ACCOUNT"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="15sp" />
<com.chaos.view.PinView
android:id="@+id/pin_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:itemCount="6"
app:itemWidth="50dp"
app:itemHeight="50dp"
android:gravity="center"
android:layout_gravity="center"
android:textColor="#000000"
android:layout_marginTop="20dp"
app:lineColor="#000000"
android:itemBackground="#ffffff"
style="@style/PinWidget.PinView"
android:inputType="number"
android:cursorVisible="true"
app:cursorColor="#000000"
app:hideLineWhenFilled="true"
app:itemRadius="5dp"/>
<TextView
android:id="@+id/verifyBtn"
android:layout_below="@id/forget_password_phone_number"
android:background="@drawable/button_background"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:layout_marginTop="30dp"
android:textColor="#FFFFFF"
android:text="VERIFY CODE"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:fontFamily="@font/muli"
android:gravity="center"
android:layout_marginTop="20dp"
android:text="or"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="20sp" />
<TextView
android:id="@+id/goEmailRegistration"
android:layout_below="@id/forget_password_phone_number"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center"
android:layout_marginTop="20dp"
android:textColor="#FFFFFF"
android:text="SIGNUP WITH EMAIL"/>
</LinearLayout>
</RelativeLayout>
In here I am using “PinView” to design the pin view section. this also a dependency. Copy this below code and paste it in the build.gradle(app) file.
//OTP pin view design
implementation 'com.chaos.view:pinview:1.4.4'
And sync it.
Backend Part 01 – Phone Number Enter Screen’s Java file
Design part is done. Now we need to implement the backend part. Let’s get back to phone number enter screen’s Java file. First we need to connect the Firebase. If you don’t know “How to connect firebase to your Android Project“, click here to refer that. Then Enable the Phone number Authentication. If you don’t know “how to enable the phone authentication“, Click here to refer that. In this enable phone authentication article has “how to enable the email”. Don’t worry. Same step for enable phone number. Just try it. it’s easy.
Then we nee to assign our text boxes and buttons in the Java file
private TextView nextBtn;
private ImageView back_btn;
private CountryCodePicker country_code_picker;
private TextInputLayout create_account_phone_number, reg_fullname;
private FirebaseAuth mAuth;
Then inside the onCreate() method, declare those variables. Like this.
country_code_picker = findViewById(R.id.country_code_picker);
reg_fullname = findViewById(R.id.reg_phone_fullname);
create_account_phone_number = (TextInputLayout) findViewById(R.id.create_account_phone_number);
nextBtn = findViewById(R.id.createAccountNextBtn);
Then create the firebase authentication instance. like this.
mAuth = FirebaseAuth.getInstance();
I am going to develop this screen when click the Next button in the phone number enter screen, pass the phone number to the verification screen. Let’s try this. Here is the code.
nextBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String full_name = reg_fullname.getEditText().getText().toString();
String getPhoneNumber = create_account_phone_number.getEditText().getText().toString().trim();
if (!TextUtils.isEmpty(full_name) || !TextUtils.isEmpty(getPhoneNumber) ) {
if (getPhoneNumber.length() == 10 ){
if (getPhoneNumber.charAt(0) == '0') {
getPhoneNumber = getPhoneNumber.substring(1);
}
String _phoneNo = "+" + country_code_picker.getFullNumber() + getPhoneNumber;
Intent goPhone = new Intent(getApplicationContext(), verificationActivity.class);
goPhone.putExtra("phoneNo", _phoneNo);
startActivity(goPhone);
}else {
create_account_phone_number.setError("need 9 digits with 0");
}
}else {
reg_fullname.setError("Field can not be empty");
create_account_phone_number.setError("Field can not be empty");
}
}
});
First I am checking text fields are empty or not. That is why I use this below code.
if (!TextUtils.isEmpty(full_name) || !TextUtils.isEmpty(getPhoneNumber) )
Then I remove when the phone number has the “0′ value. Before that, I am checking the number has 10 digits or not. Because my country has 10 digits.
if (getPhoneNumber.length() == 10 ){
if (getPhoneNumber.charAt(0) == '0') {
getPhoneNumber = getPhoneNumber.substring(1);
}
}
Then I am passing the phone number with the intent.
Backend Part 02 – Verification Screen’s Java file | Android OTP verification using firebase
Let’s get back to verification java file. First declare variables. Then assign those variables in the onCreate() method.
PinView pin_view;
private FirebaseAuth mAuth;
String codeBySystem;
TextView verifyBtn, goEmailRegistration;
pin_view = findViewById(R.id.pin_view);
mAuth = FirebaseAuth.getInstance();
verifyBtn = findViewById(R.id.verifyBtn);
goEmailRegistration = findViewById(R.id.goEmailRegistration);
Set the setOnClickListener method to the verify button. Inside that paste the below code.
String code = pin_view.getText().toString();
if (!code.isEmpty()){
verifyCode(code);
}
Create another method, outside of the onCreate method called “verifyCode()”. And paste this code inside it.
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codeBySystem, code);
signInWithPhoneAuthCredential(credential);
Create another method called signInWithPhoneAuthCredential(PhoneAuthCredential credential) outside the onCreate method and paste this code inside it.
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Intent goSetuo = new Intent(verificationActivity.this, HomeActivity.class);
startActivity(goSetuo);
finish();
} else {
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(verificationActivity.this,"Verification not Completed",Toast.LENGTH_LONG).show();
}
}
}
});
Then create another method called “sendVerificationCodeToUser”. like this.
private void sendVerificationCodeToUser(String phoneNo) {
PhoneAuthOptions options =
PhoneAuthOptions.newBuilder(mAuth)
.setPhoneNumber(phoneNo) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(this) // Activity (for callback binding)
.setCallbacks(mCallbacks) // OnVerificationStateChangedCallbacks
.build();
PhoneAuthProvider.verifyPhoneNumber(options);
}
After that paste this below method outsidein the onCreate method.
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks =
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onCodeSent(@NonNull String s, @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
codeBySystem = s;
}
@Override
public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
String code = phoneAuthCredential.getSmsCode();
if (code != null){
pin_view.setText(code);
verifyCode(code);
}
}
@Override
public void onVerificationFailed(@NonNull FirebaseException e) {
Toast.makeText(verificationActivity.this,e.getMessage(),Toast.LENGTH_LONG).show();
}
};
Finally inside the onCreate method, paste the below code.
String _phoneNo = getIntent().getStringExtra("phoneNo");
sendVerificationCodeToUser(_phoneNo);
Okay. now ready to run. Let’s check your code with my one. Follow the below full code.
PinView pin_view;
private FirebaseAuth mAuth;
String codeBySystem;
TextView verifyBtn, goEmailRegistration;
private ImageView back_btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_verification);
pin_view = findViewById(R.id.pin_view);
mAuth = FirebaseAuth.getInstance();
verifyBtn = findViewById(R.id.verifyBtn);
goEmailRegistration = findViewById(R.id.goEmailRegistration);
goEmailRegistration.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent goSignUpEmail = new Intent(verificationActivity.this, RegEmailActivity.class);
startActivity(goSignUpEmail);
finish();
}
});
back_btn = findViewById(R.id.back_btn);
back_btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent goBack = new Intent(verificationActivity.this, RegPhoneActivity.class);
startActivity(goBack);
finish();
}
});
String _phoneNo = getIntent().getStringExtra("phoneNo");
sendVerificationCodeToUser(_phoneNo);
verifyBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String code = pin_view.getText().toString();
if (!code.isEmpty()){
verifyCode(code);
}
}
});
}
private void sendVerificationCodeToUser(String phoneNo) {
PhoneAuthOptions options =
PhoneAuthOptions.newBuilder(mAuth)
.setPhoneNumber(phoneNo) // Phone number to verify
.setTimeout(60L, TimeUnit.SECONDS) // Timeout and unit
.setActivity(this) // Activity (for callback binding)
.setCallbacks(mCallbacks) // OnVerificationStateChangedCallbacks
.build();
PhoneAuthProvider.verifyPhoneNumber(options);
}
private PhoneAuthProvider.OnVerificationStateChangedCallbacks mCallbacks =
new PhoneAuthProvider.OnVerificationStateChangedCallbacks() {
@Override
public void onCodeSent(@NonNull String s, @NonNull PhoneAuthProvider.ForceResendingToken forceResendingToken) {
super.onCodeSent(s, forceResendingToken);
codeBySystem = s;
}
@Override
public void onVerificationCompleted(@NonNull PhoneAuthCredential phoneAuthCredential) {
String code = phoneAuthCredential.getSmsCode();
if (code != null){
pin_view.setText(code);
verifyCode(code);
}
}
@Override
public void onVerificationFailed(@NonNull FirebaseException e) {
Toast.makeText(verificationActivity.this,e.getMessage(),Toast.LENGTH_LONG).show();
}
};
private void verifyCode(String code){
PhoneAuthCredential credential = PhoneAuthProvider.getCredential(codeBySystem, code);
signInWithPhoneAuthCredential(credential);
}
private void signInWithPhoneAuthCredential(PhoneAuthCredential credential) {
mAuth.signInWithCredential(credential)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
Intent goSetuo = new Intent(verificationActivity.this, HomeActivity.class);
startActivity(goSetuo);
finish();
} else {
if (task.getException() instanceof FirebaseAuthInvalidCredentialsException) {
Toast.makeText(verificationActivity.this,"Verification not Completed",Toast.LENGTH_LONG).show();
}
}
}
});
}
Now you can run your code.
Thank you. Make sure to leave a comment.
If you are a newbie to Android. Follow and refer articles. Click below link to get started.
- Mobile Application Design and Development
- Data Handling in Mobile Application Development
- XML Layout – UI design for android
- How to Create Welcome Screen in Android Studio
- How to create bottom Navigation Bar in Android
- Adding Share Button – Android Studio
- How to download files Firebase to Android device
- How to create Music Player with Firebase
Other articles from different categories.
- Android Studio Articles – https://builditmasters.com/category/android-studio/
- Android Studio Firebase Tutorial – https://builditmasters.com/category/android-studio-firebase-tutorial/
- C Programming – https://builditmasters.com/category/programming/
- Flutter – https://builditmasters.com/category/flutter/
- GitHub Tutorials – https://builditmasters.com/category/github/
- Java Programming – https://builditmasters.com/category/java-programming/
- MERN / MEVN Stacks – https://builditmasters.com/category/mern_mevn_stacks/
- Tech News – https://builditmasters.com/category/tech-news/
- Theory Lessons – https://builditmasters.com/category/theory-lessons/
- Adobe Tutorials – https://builditmasters.com/category/adobe-tutorials/
- Best Website for Programming – https://builditmasters.com/category/best-website-for-programming/
- Different Programming Styles – https://builditmasters.com/category/different-programming-styles/
- Earn Money – https://builditmasters.com/category/earn-money/
- Social Word – https://builditmasters.com/category/social-world/