A Complete Guide to Firebase Multifactor Authentication in Flutter | Codemagic Blog
This article is originally posted to Codemagic blog and written by Hrishikesh Pathak
Authentication is a crucial part of your application. Failing to handle your authentication flow with caution can create a lot of problems for your business. In this era of rising security risks on popular websites and apps, it is very important to add multifactor authentication to your application.
Multifactor authentication adds another security layer to your app, helping users to retain their accounts even if their password is compromised. Most of the time, it’s best to add multiple factors of authentication to strengthen the security of your app and protect your users.
Adding a multifactor authentication system to your app from the ground up can be very involved and challenging. Fortunately, Firebase provides a highly secure and intuitive way to implement multifactor authentication in your application. If you’ve previously used Firebase authentication in your application, you just have to extend your codebase to add new authentication factors. It’s that easy.
What you’ll learn in this article
In this article, we are going to discuss how to add multifactor authentication to your Flutter application using Firebase. This post is for beginners, and I describe each step of the process in detail.
If you haven’t used Firebase authentication in your Flutter app before, this guide may be the best resource to learn how to do so. In addition to learning about basic authentication flow, you’ll also find out how to add multifactor authentication using Firebase.
This guide will be very beginner-friendly and in depth. You should avoid skipping steps and make sure to read until the end.
You can find the final version of the code on my GitHub. Clone it and run it on your device to see the final result.
Add Firebase to your Flutter project
First, go to the Firebase console and create a new project for your application. Then click on the Flutter icon on the home page. This will guide you through the steps for adding Firebase to your Flutter app.
Complete these steps and go to the next section. If you’re confused and unable to follow the above steps, here’s a brief explanation of how to add Firebase to your Flutter app.
First, download and install the Firebase CLI to your device. I have described the installation process in detail in our blog article on how to use Firebase emulator with Flutter. Please follow this guide step by step.
After installing Firebase CLI in your application, create a new Flutter project. If you already have a Flutter project, navigate to the project directory using your terminal.
Install and activate the Flutterfire CLI on your device. This CLI handles all the heavy lifting in terms of adding and configuring Firebase projects in Flutter.
dart pub global activate flutterfire_cli
Now, in the root of your project, run the following command to register the Flutter app with the Firebase project you created previously.
flutterfire configure --project=<Add your project ID> -y
After the command has been successfully completed, a new file lib/firebase_options.dart
is generated in your Flutter project. You must use this app to configure Firebase in your Flutter app.
Now add two Firebase dependencies, firebase_core and firebase_auth, in your Flutter application. Run the following command in your project root to install these dependencies.
dart pub add firebase_core firebase_auth
Next, import these dependencies in your main.dart
file, and configure Firebase in your Flutter app.
As you can see in the above snippet, I am using the DefaultFirebaseOptions.currentPlatform
method from the firebase_options.dart
file generated by flutterfire_cli.
Email password authentication using Firebase in Flutter
Email password authentication is the most basic form of authentication. Despite this, it’s the most widely used type of authentication, especially on website login forms.
Before proceeding any further, go to your Firebase console and open the authentication page. Then click on the Email/Password button and enable email password authentication in your Firebase project.
To get the email and password from the user, we need to have two TextField
s and two respective TextEditingController
s in our Flutter app.
late final TextEditingController _emailController; late final TextEditingController _passwordController; @override void initState() { _emailController = TextEditingController(); _passwordController = TextEditingController(); super.initState(); } @override void dispose() { _emailController.dispose(); _passwordController.dispose(); super.dispose(); }
Make sure to dispose of these TextEditingController
s using the dispose
method after you assign them to your application.
Now assign these controllers in their respective TextField
s.
@override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ TextField( controller: _emailController, ), TextField( controller: _passwordController, ), ], ), ); }
User email verification using Firebase authentication
late final StreamSubscription _firebaseStreamEvents; @override void initState() { _firebaseStreamEvents = FirebaseAuth.instance.authStateChanges().listen((user) { print(user); }); super.initState(); } @override void dispose() { _firebaseStreamEvents.cancel(); super.dispose(); }
Once you subscribe to the stream in a widget, make sure to cancel the stream subscription using the dispose method.
When a user is successfully registered in the application, a new User
is emitted from the authStateChanges
stream. You can listen to this event and send a verification email to the recently registered user.
_firebaseStreamEvents = FirebaseAuth.instance.authStateChanges().listen((user) { print(user); if (user != null) { user.sendEmailVerification(); } } );
Now the registered user receives a verification email from the Firebase in their email address. During development, the verification email usually goes to the spam folder. Check your email spam folder if you haven’t gotten any email from Firebase after invoking the user.sendEmailVerification
function.
Prerequisites for adding multifactor authentication in Firebase
A new event emits from the Firebase authStateChanges
stream when a user verifies their email. You can listen to this event and redirect the user to the multifactor authentication page. On the multifactor authentication page, you collect the user's phone number to add as the second authentication factor.
_firebaseStreamEvents = FirebaseAuth.instance.authStateChanges().listen((user) { if (user != null) { if (user.emailVerified) { Navigator.of(context).push( MaterialPageRoute( builder: (context) => const MultiAuthPage(), ), ); } else { user.sendEmailVerification(); } } } );
Add multifactor authentication in Flutter using Firebase
To add multifactor authentication in your Flutter app with Firebase, first, go to the Firebase console. Navigate to the Authentication section. Now you can see the SMS multifactor authentication tab. Click on the Upgrade to enable button.
A guided pop-up will appear regarding Firebase multifactor authentication. Read it carefully and click on the Upgrade to the new authentication button.
Now, inside the SMS multifactor authentication tab, you can enable the Firebase multifactor authentication process. You can also add some dummy phone numbers with verification codes for testing purposes.
To start a multifactor authentication process, first, acquire a MultiFactorSession
from the FirebaseAuth
instance.
onPressed: () async { MultiFactorSession session = await FirebaseAuth.instance.currentUser!.multiFactor.getSession(); },
Now, use this session inside the verifyPhoneNumber
method of the FirebaseAuth
instance, along with the user's phone number.
In the above code snippets, you can see that I am using the getSmsCodeFromUser(context)
function to get the SMS code from the user. This function opens an AlertDialog
to enter the SMS code and return the code input to use in our multifactor authentication process.
This code snippet is taken from this Flutter GitHub repository example.
Sign in a user using multifactor authentication
At this point, we have registered a user using Firebase multifactor authentication in our Flutter application. Now let’s see how to sign in a user using multifactor authentication.
try { await _auth.signInWithEmailAndPassword( email: emailController.text, password: passwordController.text, ); } on FirebaseAuthMultiFactorException catch (e) { final resolver = e.resolver }
Now, use this resolver to get the session for multifactor authentication.
Similar to the registration process, you can use the verifyPhoneNumber
method of the FirebaseAuth
instance and pass the session you get from the resolver in the previous step along with the user's phone number.
Build your Flutter app with Codemagic
Codemagic is a CI/CD platform for Flutter applications. You can trigger a new Flutter build when you push your code to your GitHub repository. Then just download the generated artifacts from the Codemagic dashboard and run them on your devices. Let’s go over the steps for integrating Codemagic CI/CD in your Flutter application.
curl -sL https://firebase.tools | bash dart pub global activate flutterfire_cli
flutterfire configure --project=fir-multi-auth-15644 --platforms= "android" --ios-bundle-id= "com.example.firebase_multifactor_auth" --macos-bundle-id= "com.example.firebase_multifactor_auth" --android-package-name= "com.example.firebase_multifactor_auth" -y
- Click on the Start new build button to initiate the first build of your application.
- After the build completes, you can download the artifacts and run them on your devices.
Conclusion
In this article, I have shown you how to add multifactor authentication using Firebase to your Flutter application. This is a very simple process to implement. First, you create a simple email password login flow with an email verification process. Then you add the user’s phone number as a second authentication factor. Note that multifactor authentication is enabled only for email-verified users. If your user is not email verified, make sure they do this first before using multifactor authentication.
If you like this article, share it with your friends, and check out my personal blog. If you have any questions, you can ask me on Twitter. Have a good day.