Add multi-factor authentication to your Flutter app Stay organized with collections Save and categorize content based on your preferences.
If you've upgraded to Firebase Authentication with Identity Platform,you can add SMS multi-factor authentication to your Flutter app.
Note: Avoid the use of SMS-based MFA. SMS is an insecure technology that is easy to compromise or spoof withno authentication mechanism or eavesdropping protection.Multi-factor authentication (MFA) increases the security of your app. While attackersoften compromise passwords and social accounts, intercepting a text message ismore difficult.
Before you begin
Note: Windows platform does not support multi-factor authentication. Using multi-factor authentication withmultiple tenants on any platformis not supported on Flutter.Enable at least one provider that supports multi-factor authentication.Every provider supports MFA,except phone auth, anonymous auth, andApple Game Center.
Ensure your app is verifying user emails. MFA requires email verification.This prevents malicious actors from registering for a service with an emailthey don't own, and then locking out the real owner by adding a secondfactor.
Android: If you haven't already set your app's SHA-256 hash in theFirebase console, do so.SeeAuthenticating Your Clientfor information about finding your app's SHA-256 hash.
iOS: In Xcode,enable push notifications for your project & ensureyour APNs authentication key isconfigured with Firebase Cloud Messaging (FCM). Additionally, you mustenable background modes for remote notifications.To view an in-depth explanation of this step, view theFirebase iOS Phone Auth documentation.
Web: Ensure that you have added your applications domain on theFirebase console, underOAuth redirect domains.
Enabling multi-factor authentication
Open theAuthentication > Sign-in methodpage of the Firebase console.
In theAdvanced section, enableSMS Multi-factor Authentication.
You should also enter the phone numbers you'll be testing your app with.While optional, registering test phone numbers is strongly recommended toavoid throttling during development.
If you haven't already authorized your app's domain, add it to the allowlist on theAuthentication > Settingspage of the Firebase console.
Choosing an enrollment pattern
You can choose whether your app requires multi-factor authentication, and howand when to enroll your users. Some common patterns include:
Enroll the user's second factor as part of registration. Use thismethod if your app requires multi-factor authentication for all users.
Offer a skippable option to enroll a second factor during registration. Appsthat want to encourage, but not require, multi-factor authentication mightprefer this approach.
Provide the ability to add a second factor from the user's account or profilemanagement page, instead of the sign up screen. This minimizes friction duringthe registration process, while still making multi-factor authenticationavailable for security-sensitive users.
Require adding a second factor incrementally when the user wants to accessfeatures with increased security requirements.
Enrolling a second factor
To enroll a new secondary factor for a user:
Re-authenticate the user.
Ask the user enter their phone number.
Note: Google stores and uses phone numbers to improve spam and abuseprevention across all Google services. Ensure you obtain appropriate consentfrom your users before sending their phone numbers toFirebase.Get a multi-factor session for the user:
finalmultiFactorSession=awaituser.multiFactor.getSession();Verify the phone number with a multi factor session and your callbacks:
awaitFirebaseAuth.instance.verifyPhoneNumber(multiFactorSession:multiFactorSession,phoneNumber:phoneNumber,verificationCompleted:(_){},verificationFailed:(_){},codeSent:(StringverificationId,int?resendToken)async{// The SMS verification code has been sent to the provided phone number.// ...},codeAutoRetrievalTimeout:(_){},);Once the SMS code is sent, ask the user to verify the code:
finalcredential=PhoneAuthProvider.credential(verificationId:verificationId,smsCode:smsCode,);Complete the enrollment:
awaituser.multiFactor.enroll(PhoneMultiFactorGenerator.getAssertion(credential,),);
The code below shows a complete example of enrolling a second factor:
finalsession=awaituser.multiFactor.getSession();finalauth=FirebaseAuth.instance;awaitauth.verifyPhoneNumber(multiFactorSession:session,phoneNumber:phoneController.text,verificationCompleted:(_){},verificationFailed:(_){},codeSent:(StringverificationId,int?resendToken)async{// See `firebase_auth` example app for a method of retrieving user's sms code:// https://github.com/firebase/flutterfire/blob/main/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591finalsmsCode=awaitgetSmsCodeFromUser(context);if(smsCode!=null){// Create a PhoneAuthCredential with the codefinalcredential=PhoneAuthProvider.credential(verificationId:verificationId,smsCode:smsCode,);try{awaituser.multiFactor.enroll(PhoneMultiFactorGenerator.getAssertion(credential,),);}onFirebaseAuthExceptioncatch(e){print(e.message);}}},codeAutoRetrievalTimeout:(_){},);Congratulations! You successfully registered a second authentication factor fora user.
Important: You should strongly encourage your users to register more than onesecond factor for account recovery purposes. If a user only registers a singlesecond factor and later loses access to it, they will be locked out of theiraccount.Signing users in with a second factor
To sign in a user with two-factor SMS verification:
Sign the user in with their first factor, then catch the
FirebaseAuthMultiFactorExceptionexception. This error contains aresolver, which you can use to obtain the user's enrolled second factors.It also contains an underlying session proving the user successfullyauthenticated with their first factor.For example, if the user's first factor was an email and password:
try{await_auth.signInWithEmailAndPassword(email:emailController.text,password:passwordController.text,);// User is not enrolled with a second factor and is successfully// signed in.// ...}onFirebaseAuthMultiFactorExceptioncatch(e){// The user is a multi-factor user. Second factor challenge is requiredfinalresolver=e.resolver// ...}If the user has multiple secondary factors enrolled, ask them which oneto use:
finalsession=e.resolver.session;finalhint=e.resolver.hints[selectedHint];Send a verification message to the user's phone with the hint andmulti-factor session:
awaitFirebaseAuth.instance.verifyPhoneNumber(multiFactorSession:session,multiFactorInfo:hint,verificationCompleted:(_){},verificationFailed:(_){},codeSent:(StringverificationId,int?resendToken)async{// ...},codeAutoRetrievalTimeout:(_){},);Call
resolver.resolveSignIn()to complete secondary authentication:finalsmsCode=awaitgetSmsCodeFromUser(context);if(smsCode!=null){// Create a PhoneAuthCredential with the codefinalcredential=PhoneAuthProvider.credential(verificationId:verificationId,smsCode:smsCode,);try{awaite.resolver.resolveSignIn(PhoneMultiFactorGenerator.getAssertion(credential));}onFirebaseAuthExceptioncatch(e){print(e.message);}}
The code below shows a complete example of signing in a multi-factor user:
try{await_auth.signInWithEmailAndPassword(email:emailController.text,password:passwordController.text,);}onFirebaseAuthMultiFactorExceptioncatch(e){setState((){error='${e.message}';});finalfirstHint=e.resolver.hints.first;if(firstHintis!PhoneMultiFactorInfo){return;}awaitFirebaseAuth.instance.verifyPhoneNumber(multiFactorSession:e.resolver.session,multiFactorInfo:firstHint,verificationCompleted:(_){},verificationFailed:(_){},codeSent:(StringverificationId,int?resendToken)async{// See `firebase_auth` example app for a method of retrieving user's sms code:// https://github.com/firebase/flutterfire/blob/main/packages/firebase_auth/firebase_auth/example/lib/auth.dart#L591finalsmsCode=awaitgetSmsCodeFromUser(context);if(smsCode!=null){// Create a PhoneAuthCredential with the codefinalcredential=PhoneAuthProvider.credential(verificationId:verificationId,smsCode:smsCode,);try{awaite.resolver.resolveSignIn(PhoneMultiFactorGenerator.getAssertion(credential,),);}onFirebaseAuthExceptioncatch(e){print(e.message);}}},codeAutoRetrievalTimeout:(_){},);}catch(e){...}Congratulations! You successfully signed in a user using multi-factorauthentication.
What's next
- Manage multi-factor usersprogrammatically with the Admin SDK.
Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.
Last updated 2025-10-29 UTC.