Authenticate with Firebase on Android using a Phone Number
Stay organized with collectionsSave and categorize content based on your preferences.
You can useFirebase Authenticationto 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.
The easiest way to add phone number sign-in to your app is to useFirebaseUI,
which includes a drop-in sign-in widget that implements sign-in flows for phone
number sign-in, as well as password-based and federated sign-in. This document
describes how to implement a phone number sign-in flow using the Firebase SDK.
In yourmodule (app-level) Gradle file(usually<project>/<app-module>/build.gradle.ktsor<project>/<app-module>/build.gradle),
add the dependency for theFirebase Authenticationlibrary for Android. We recommend using theFirebase Android BoMto control library versioning.
dependencies{// Import theBoMfor the Firebase platformimplementation(platform("com.google.firebase:firebase-bom:34.2.0"))// Add the dependency for theFirebase Authenticationlibrary// When using theBoM, you don't specify versions in Firebase library dependenciesimplementation("com.google.firebase:firebase-auth")}
By using theFirebase Android BoM,
your app will always use compatible versions of Firebase Android libraries.
(Alternative)
Add Firebase library dependencies without using theBoM
If you choose not to use theFirebase BoM, you must specify each Firebase library version
in its dependency line.
Note that if you usemultipleFirebase libraries in your app, we strongly
recommend using theBoMto manage library versions, which ensures that all versions are
compatible.
dependencies{// Add the dependency for theFirebase Authenticationlibrary// When NOT using theBoM, you must specify versions in Firebase library dependenciesimplementation("com.google.firebase:firebase-auth:24.0.1")}
If you haven't yet connected your app to your Firebase project, do so from
theFirebaseconsole.
Authentication using only a phone number, while convenient, is less secure
than the other available methods, because possession of a phone number
can be easily transferred between users. Also, on devices with multiple user
profiles, any user that can receive SMS messages can sign in to an account using
the device's phone number.
If you use phone number based sign-in in your app, you should offer it
alongside more secure sign-in methods, and inform users of the security
tradeoffs of using phone number sign-in.
Enable Phone Number sign-in for your Firebase project
To sign in users by SMS, you must first enable the Phone Number sign-in
method for your Firebase project:
On theSign-in Methodpage, enable thePhone Numbersign-in method.
Optional: On theSettingspage, set a policy on the regions to which you want
to allow or deny SMS messages to be sent. Setting an SMS region policy can help protect your
apps from SMS abuse.
Enable app verification
To use phone number authentication, Firebase must be able to verify that
phone number sign-in requests are coming from your app. There are three waysFirebase Authenticationaccomplishes this:
Play Integrity API: If a user has a device withGoogle Playservicesinstalled,
andFirebase Authenticationcan verify the device as legitimate with thePlay Integrity API,
phone number sign-in can proceed. The Play Integrity API is enabled on a Google-owned project byFirebase Authentication, not on your project. This does not contribute to any Play Integrity API
quotas on your project. Play Integrity Support is available with theAuthenticationSDK v21.2.0+(Firebase BoMv31.4.0+).
To use Play Integrity, if you haven't yet specified your app's SHA-256 fingerprint, do so
from theProject
settingsof theFirebaseconsole. Refer toAuthenticating Your
Clientfor details on how to get your app's SHA-256 fingerprint.
reCAPTCHA verification: In the event that Play Integrity cannot be used,
such as when a user has a devicewithoutGoogle Playservicesinstalled,Firebase Authenticationuses a reCAPTCHA verification to complete the phone sign-in flow. The reCAPTCHA challenge can
often be completed without the user having to solve anything. Note that this flow requires that
a SHA-1 is associated with your application. This flow also requires your API Key to be
unrestricted or allowlisted forPROJECT_ID.firebaseapp.com.
Some scenarios where reCAPTCHA is triggered:
If the end-user's device does not haveGoogle Playservicesinstalled.
If the obtained SafetyNet token was not valid (onAuthenticationSDK versions < v21.2.0).
When SafetyNet or Play Integrity is used for App verification, the%APP_NAME%field in the SMS template is populated with the app name determined fromGoogle PlayStore.
In the scenarios where reCAPTCHA is triggered,%APP_NAME%is populated asPROJECT_ID.firebaseapp.com.
"Missing initial state" error when using reCAPTCHA for app verification
This can occur when the reCAPTCHA flow completes successfully but does not redirect the user back to the native application. If this occurs, the user is redirected to the fallback URLPROJECT_ID.firebaseapp.com/__/auth/handler.
On Firefox browsers, opening native app links is disabled by default. If you see the above error on Firefox, follow the steps inSet Firefox for Android to open links in native appsto enable opening app links.
Send a verification code to the user's phone
To initiate phone number sign-in, present the user an interface that prompts
them to type their phone number. Legal requirements vary, but as a best practice
and to set expectations for your users, you should inform them that if they use
phone sign-in, they might receive an SMS message for verification and standard
rates apply.
Then, pass their phone number to thePhoneAuthProvider.verifyPhoneNumbermethod to request that Firebase
verify the user's phone number. For example:
Kotlin
valoptions=PhoneAuthOptions.newBuilder(auth).setPhoneNumber(phoneNumber)// Phone number to verify.setTimeout(60L,TimeUnit.SECONDS)// Timeout and unit.setActivity(this)// Activity (for callback binding).setCallbacks(callbacks)// OnVerificationStateChangedCallbacks.build()PhoneAuthProvider.verifyPhoneNumber(options)
PhoneAuthOptionsoptions=PhoneAuthOptions.newBuilder(mAuth).setPhoneNumber(phoneNumber)// Phone number to verify.setTimeout(60L,TimeUnit.SECONDS)// Timeout and unit.setActivity(this)// (optional) Activity for callback binding// If no activity is passed, reCAPTCHA verification can not be used..setCallbacks(mCallbacks)// OnVerificationStateChangedCallbacks.build();PhoneAuthProvider.verifyPhoneNumber(options);
TheverifyPhoneNumbermethod is reentrant: if you call it
multiple times, such as in an activity'sonStartmethod, theverifyPhoneNumbermethod will not send a second SMS unless the
original request has timed out.
You can use this behavior to resume the phone number sign in process if your
app closes before the user can sign in (for example, while the user is using
their SMS app). After you callverifyPhoneNumber, set a flag that
indicates verification is in progress. Then, save the flag in your Activity'sonSaveInstanceStatemethod and restore the flag inonRestoreInstanceState. Finally, in your Activity'sonStartmethod, check if verification is already in progress, and
if so, callverifyPhoneNumberagain. Be sure to clear the flag when
verification completes or fails (seeVerification callbacks).
To easily handle screen rotation and other instances of Activity restarts,
pass your Activity to theverifyPhoneNumbermethod. The callbacks
will be auto-detached when the Activity stops, so you can freely write UI
transition code in the callback methods.
The SMS message sent by Firebase can also be localized by specifying the
auth language via thesetLanguageCodemethod on your Auth
instance.
Kotlin
auth.setLanguageCode("fr")// To apply the default app language instead of explicitly setting it.// auth.useAppLanguage()
When you callPhoneAuthProvider.verifyPhoneNumber, you must also
provide an instance ofOnVerificationStateChangedCallbacks, which
contains implementations of the callback functions that handle the results of
the request. For example:
Kotlin
callbacks=object:PhoneAuthProvider.OnVerificationStateChangedCallbacks(){overridefunonVerificationCompleted(credential:PhoneAuthCredential){// 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)}overridefunonVerificationFailed(e:FirebaseException){// 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(eisFirebaseAuthInvalidCredentialsException){// Invalid request}elseif(eisFirebaseTooManyRequestsException){// The SMS quota for the project has been exceeded}elseif(eisFirebaseAuthMissingActivityForRecaptchaException){// reCAPTCHA verification attempted with null Activity}// Show a message and update the UI}overridefunonCodeSent(verificationId:String,token:PhoneAuthProvider.ForceResendingToken,){// 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 laterstoredVerificationId=verificationIdresendToken=token}}
mCallbacks=newPhoneAuthProvider.OnVerificationStateChangedCallbacks(){@OverridepublicvoidonVerificationCompleted(@NonNullPhoneAuthCredentialcredential){// 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);}@OverridepublicvoidonVerificationFailed(@NonNullFirebaseExceptione){// 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(einstanceofFirebaseAuthInvalidCredentialsException){// Invalid request}elseif(einstanceofFirebaseTooManyRequestsException){// The SMS quota for the project has been exceeded}elseif(einstanceofFirebaseAuthMissingActivityForRecaptchaException){// reCAPTCHA verification attempted with null Activity}// Show a message and update the UI}@OverridepublicvoidonCodeSent(@NonNullStringverificationId,@NonNullPhoneAuthProvider.ForceResendingTokentoken){// 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 latermVerificationId=verificationId;mResendToken=token;}};
In most apps, you implement theonVerificationCompleted,onVerificationFailed, andonCodeSentcallbacks. You
might also implementonCodeAutoRetrievalTimeOut, depending on your
app's requirements.
onVerificationCompleted(PhoneAuthCredential)
This method is called in two situations:
Instant verification: in some cases the phone number can be instantly
verified without needing to send or enter a verification code.
Auto-retrieval: on some devices, Google Play services can
automatically detect the incoming verification SMS and perform
verification without user action. (This capability might be unavailable
with some carriers.) This uses theSMS Retriever API, which
includes an 11 character hash at the end of the SMS message.
In either case, the user's phone number has been verified successfully, and
you can use thePhoneAuthCredentialobject that's passed to the
callback tosign in the user.
onVerificationFailed(FirebaseException)
This method is called in response to an invalid verification request, such
as a request that specifies an invalid phone number or verification code.
Optional. This method is called after the verification code has been sent
by SMS to the provided phone number.
When this method is called, most apps display a UI that prompts the user
to type the verification code from the SMS message. (At the same time,
auto-verification might be proceeding in the background.) Then, after the user
types the verification code, you can use the verification code and the
verification ID that was passed to the method to create aPhoneAuthCredentialobject, which you can in turn use to sign in
the user. However, some apps might wait untilonCodeAutoRetrievalTimeOutis called before displaying the
verification code UI (not recommended).
onCodeAutoRetrievalTimeOut(String verificationId)
Optional. This method is called after the timeout duration specified toverifyPhoneNumberhas passed withoutonVerificationCompletedtriggering first. On devices without SIM
cards, this method is called immediately because SMS auto-retrieval isn't
possible.
Some apps block user input until the auto-verification period has timed out,
and only then display a UI that prompts the user to type the verification code
from the SMS message (not recommended).
Create a PhoneAuthCredential object
After the user enters the verification code that Firebase sent to the user's
phone, create aPhoneAuthCredentialobject, using the verification
code and the verification ID that was passed to theonCodeSentoronCodeAutoRetrievalTimeOutcallback. (WhenonVerificationCompletedis called, you get aPhoneAuthCredentialobject directly, so you can skip this step.)
To create thePhoneAuthCredentialobject, callPhoneAuthProvider.getCredential:
After you get aPhoneAuthCredentialobject, whether in theonVerificationCompletedcallback or by callingPhoneAuthProvider.getCredential, complete the sign-in flow by
passing thePhoneAuthCredentialobject toFirebaseAuth.signInWithCredential:
Kotlin
privatefunsignInWithPhoneAuthCredential(credential:PhoneAuthCredential){auth.signInWithCredential(credential).addOnCompleteListener(this){task->if(task.isSuccessful){// Sign in success, update UI with the signed-in user's informationLog.d(TAG,"signInWithCredential:success")valuser=task.result?.user}else{// Sign in failed, display a message and update the UILog.w(TAG,"signInWithCredential:failure",task.exception)if(task.exceptionisFirebaseAuthInvalidCredentialsException){// The verification code entered was invalid}// Update UI}}}
privatevoidsignInWithPhoneAuthCredential(PhoneAuthCredentialcredential){mAuth.signInWithCredential(credential).addOnCompleteListener(this,newOnCompleteListener<AuthResult>(){@OverridepublicvoidonComplete(@NonNullTask<AuthResult>task){if(task.isSuccessful()){// Sign in success, update UI with the signed-in user's informationLog.d(TAG,"signInWithCredential:success");FirebaseUseruser=task.getResult().getUser();// Update UI}else{// Sign in failed, display a message and update the UILog.w(TAG,"signInWithCredential:failure",task.getException());if(task.getException()instanceofFirebaseAuthInvalidCredentialsException){// The verification code entered was invalid}}}});}
You can set up fictional phone numbers for development via theFirebaseconsole. Testing with fictional phone
numbers provides these benefits:
Test phone number authentication without consuming your usage quota.
Test phone number authentication without sending an actual SMS message.
Run consecutive tests with the same phone number without getting throttled. This
minimizes the risk of rejection during App store review process if the reviewer happens to use
the same phone number for testing.
Test readily in development environments without any additional effort, such as
the ability to develop in an iOS simulator or an Android emulator without Google Play Services.
Write integration tests without being blocked by security checks normally applied
on real phone numbers in a production environment.
Fictional phone numbers must meet these requirements:
Make sure you use phone numbers that are indeed fictional, and do not already exist.Firebase Authenticationdoes not allow you to set existing phone numbers used by real users as test numbers.
One option is to use 555 prefixed numbers as US test phone numbers, for example:+1 650-555-3434
Phone numbers have to be correctly formatted for length and other
constraints. They will still go through the same validation as a real user's phone number.
You can add up to 10 phone numbers for development.
Use test phone numbers/codes that are hard to guess and change
those frequently.
Create fictional phone numbers and verification codes
In theSign in methodtab, enable the Phone provider if you haven't already.
Open thePhone numbers for testingaccordion menu.
Provide the phone number you want to test, for example:+1 650-555-3434.
Provide the 6-digit verification code for that specific number, for example:654321.
Addthe number. If there's a need, you can delete the phone number and
its code by hovering over the corresponding row and clicking the trash icon.
Manual testing
You can directly start using a fictional phone number in your application. This allows you to
perform manual testing during development stages without running into quota issues or throttling.
You can also test directly from an iOS simulator or Android emulator without Google Play Services
installed.
When you provide the fictional phone number and send the verification code, no actual SMS is
sent. Instead, you need to provide the previously configured verification code to complete the sign
in.
On sign-in completion, a Firebase user is created with that phone number. The
user has the same behavior and properties as a real phone number user, and can accessRealtime Database/Cloud Firestoreand other services the same way. The ID token minted during
this process has the same signature as a real phone number user.
Another option is toset a test role via custom
claimson these users to differentiate them as fake users if you want to further restrict
access.
To manually trigger the reCAPTCHA flow for testing, use theforceRecaptchaFlowForTesting()method.
// Force reCAPTCHA flowFirebaseAuth.getInstance().getFirebaseAuthSettings().forceRecaptchaFlowForTesting();
Integration testing
In addition to manual testing,Firebase Authenticationprovides APIs to help write integration tests
for phone auth testing. These APIs disable app verification by disabling the reCAPTCHA
requirement in web and silent push notifications in iOS. This makes automation testing possible in
these flows and easier to implement. In addition, they help provide the ability to test instant
verification flows on Android.
On Android, callsetAppVerificationDisabledForTesting()before thesignInWithPhoneNumbercall. This disables app verification automatically,
allowing you to pass the phone number without manually solving it. Even though
Play Integrity and reCAPTCHA are disabled, using a real phone number will still fail to
complete sign in. Only fictional phone numbers can be used with this API.
// Turn off phone auth app verification.FirebaseAuth.getInstance().getFirebaseAuthSettings().setAppVerificationDisabledForTesting();
CallingverifyPhoneNumberwith a fictional number triggers theonCodeSentcallback, in which you'll need to provide the corresponding verification
code. This allows testing in Android Emulators.
Java
StringphoneNum="+16505554567";StringtestVerificationCode="123456";// Whenever verification is triggered with the whitelisted number,// provided it is not set for auto-retrieval, onCodeSent will be triggered.FirebaseAuthauth=FirebaseAuth.getInstance();PhoneAuthOptionsoptions=PhoneAuthOptions.newBuilder(auth).setPhoneNumber(phoneNum).setTimeout(60L,TimeUnit.SECONDS).setActivity(this).setCallbacks(newPhoneAuthProvider.OnVerificationStateChangedCallbacks(){@OverridepublicvoidonCodeSent(@NonNullStringverificationId,@NonNullPhoneAuthProvider.ForceResendingTokenforceResendingToken){// Save the verification id somewhere// ...// The corresponding whitelisted code above should be used to complete sign-in.MainActivity.this.enableUserManuallyInputCode();}@OverridepublicvoidonVerificationCompleted(@NonNullPhoneAuthCredentialphoneAuthCredential){// Sign in with the credential// ...}@OverridepublicvoidonVerificationFailed(@NonNullFirebaseExceptione){// ...}}).build();PhoneAuthProvider.verifyPhoneNumber(options);
valphoneNum="+16505554567"valtestVerificationCode="123456"// Whenever verification is triggered with the whitelisted number,// provided it is not set for auto-retrieval, onCodeSent will be triggered.valoptions=PhoneAuthOptions.newBuilder(Firebase.auth).setPhoneNumber(phoneNum).setTimeout(30L,TimeUnit.SECONDS).setActivity(this).setCallbacks(object:PhoneAuthProvider.OnVerificationStateChangedCallbacks(){overridefunonCodeSent(verificationId:String,forceResendingToken:PhoneAuthProvider.ForceResendingToken,){// Save the verification id somewhere// ...// The corresponding whitelisted code above should be used to complete sign-in.this@MainActivity.enableUserManuallyInputCode()}overridefunonVerificationCompleted(phoneAuthCredential:PhoneAuthCredential){// Sign in with the credential// ...}overridefunonVerificationFailed(e:FirebaseException){// ...}}).build()PhoneAuthProvider.verifyPhoneNumber(options)
Additionally, you can test auto-retrieval flows in Android by setting the fictional number and
its corresponding verification code for auto-retrieval by callingsetAutoRetrievedSmsCodeForPhoneNumber.
WhenverifyPhoneNumberis
called, it triggersonVerificationCompletedwith thePhoneAuthCredentialdirectly. This works only with fictional phone numbers.
Make sure this is disabled and no fictional phone numbers are hardcoded in
your app when publishing your application to the Google Play store.
Java
// The test phone number and code should be whitelisted in the console.StringphoneNumber="+16505554567";StringsmsCode="123456";FirebaseAuthfirebaseAuth=FirebaseAuth.getInstance();FirebaseAuthSettingsfirebaseAuthSettings=firebaseAuth.getFirebaseAuthSettings();// Configure faking the auto-retrieval with the whitelisted numbers.firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber,smsCode);PhoneAuthOptionsoptions=PhoneAuthOptions.newBuilder(firebaseAuth).setPhoneNumber(phoneNumber).setTimeout(60L,TimeUnit.SECONDS).setActivity(this).setCallbacks(newPhoneAuthProvider.OnVerificationStateChangedCallbacks(){@OverridepublicvoidonVerificationCompleted(@NonNullPhoneAuthCredentialcredential){// Instant verification is applied and a credential is directly returned.// ...}// ...}).build();PhoneAuthProvider.verifyPhoneNumber(options);
// The test phone number and code should be whitelisted in the console.valphoneNumber="+16505554567"valsmsCode="123456"valfirebaseAuth=Firebase.authvalfirebaseAuthSettings=firebaseAuth.firebaseAuthSettings// Configure faking the auto-retrieval with the whitelisted numbers.firebaseAuthSettings.setAutoRetrievedSmsCodeForPhoneNumber(phoneNumber,smsCode)valoptions=PhoneAuthOptions.newBuilder(firebaseAuth).setPhoneNumber(phoneNumber).setTimeout(60L,TimeUnit.SECONDS).setActivity(this).setCallbacks(object:PhoneAuthProvider.OnVerificationStateChangedCallbacks(){overridefunonVerificationCompleted(credential:PhoneAuthCredential){// Instant verification is applied and a credential is directly returned.// ...}// ...}).build()PhoneAuthProvider.verifyPhoneNumber(options)
After a user signs in for the first time, a new user account is created and
linked to the credentials—that is, the user name and password, phone
number, or auth provider information—the user signed in with. This new
account is stored as part of your Firebase project, and can be used to identify
a user across every app in your project, regardless of how the user signs in.
In your apps, you can get the user's basic profile information from theFirebaseUserobject. SeeManage Users.
In yourFirebase Realtime DatabaseandCloud StorageSecurity Rules, you can
get the signed-in user's unique user ID from theauthvariable,
and use it to control what data a user can access.
[[["Easy to understand","easyToUnderstand","thumb-up"],["Solved my problem","solvedMyProblem","thumb-up"],["Other","otherUp","thumb-up"]],[["Missing the information I need","missingTheInformationINeed","thumb-down"],["Too complicated / too many steps","tooComplicatedTooManySteps","thumb-down"],["Out of date","outOfDate","thumb-down"],["Samples / code issue","samplesCodeIssue","thumb-down"],["Other","otherDown","thumb-down"]],["Last updated 2025-09-04 UTC."],[],[],null,[]]