Flutter Firebase Authentication Tutorial | Signup and Login

In any application, user authentication is a key factor for securing the app and keeping its data safe.

Firebase Authentication is a backend service made by Google that provides you with tools to easily authenticate your app’s users. It supports authentication using password, Google, Facebook, and so on.

This article will be Flutter Firebase Authentication Tutorial where I will show you how to implement Firebase authentication in Flutter step by step.

Now before we start, I’ve already created the UI design for this tutorial as I’ll be focusing on how to use Firebase in Flutter rather than UI design so you can download the startup code to get started.

So, without further ado, let’s dive right into it..

 

1. How to add Firebase to Flutter App

To get started, we’ll create a Firebase project and link it to the Flutter project we’re working on.

Create Firebase Project

The first you need to do is to create a Firebase project from Firebase Console.

  • From the console, click on add project
Flutter Firebase Authentication Tutorial
Create Firebase Project (Step 1)
  • Enter Project Name

    Flutter Firebase Authentication Tutorial
    Create Firebase Project (Step 2)
  • Next step is to enable analytics, we won’t be using Google analytics so you can disable it and click on Create Project. It’ll take a while until the project is created, click continue then you’ll be redirected to Firebase Dashboard.

    Flutter Firebase Authentication Tutorial
    Create Firebase Project (Step 3)

 

Set up Firebase for Android Platform

After creating the Firebase project, you’ll need to configure the complete the platform-specific Firebase configuration (Android, IOS, and Web). Flutter is a cross-platform framework so you’ll need to integrate Firebase project with each platform separately. In this tutorial, we’ll only be integrating Android platform.

  • From the Firebase Dashboard, select Android icon

    Flutter Firebase Authentication Tutorial
    Android Platform Integration (step 1)
  • Next you need to register your app by entering your Android package name, App nickname, and SHA-1 then click register app
    Flutter Firebase Authentication Tutorial
    Android Platform Integration (step 2)
    • You can get the Android package name under applicationId in your app-level build.gradle file
      Flutter Firebase Auth
    • App nickname is optional and can be any value you want
    • SHA-1 is only required when you want to implement google sign-in or phone number support in auth. You can get your project’s certificate SHA-1 by following the following steps:
      • open you project in Android Studio (Tools > Flutter > open for editing in Android Studio)
      • From right side panel, click on Gradle, a widow will be displayed
      • Then, from that window, click on Gradle icon then a searchable window will open
      • From that window, enter gradle signingreport  and press enter to generate the SHA-1 key
        generate sha-1 key
        Generate SHA-1 key

         

        Generate SHA-1 key
        SHA-1 Key

         

  • Next, download google-services.json and add it to Android app module root directory

    Flutter Firebase Authentication Tutorial
    Android Platform Integration (step 3)
  • Lastly, follow the instructions specified and copy the code to where the instruction says and sync Gradle to finish.

    Flutter Firebase Authentication Tutorial
    Android Platform Integration (step 4)

2. How to add Firebase Authentication to Flutter App

In order to user Firebase Authentication features, you first need to enable it in Firebase console. From Firebase Dashboard left menu, click on Authentication and then Get started then enable sign-in methods. In this tutorial, I will show you how to implement Firebase email authentication in Flutter as well as Google sign-in.

Set up Firebase Authentication from Firebase Console

  • Click on Email/Password then enable it and save
    Flutter Firebase Authentication Tutorial
  • Click on add new provider, select Google, enable, and enter project support email (your Firebase Account Email)
    Flutter Firebase Authentication Tutorial\

Add required dependencies to Flutter Project

In order to implement Firebase Authentication, there are some packages that you need to add to pubspec.yaml file in your Flutter project. Insert the following dependencies then click on Pub get.

dependencies:
  firebase_auth: ^3.3.12
  firebase_core: ^1.14.0
  google_sign_in: ^5.2.4

 

Initialize Firebase in Flutter project

Now in order to use Firebase features, you first need to create and initialize an instance of Firebase app.

  • Create a new directory “utils” then create a file “authentication.dart”. In this file, we’ll create all the methods we need for Firebase Authentication but first, let’s create a method initialize our Firebase app.

    class Authentication {
    
      static Future<FirebaseApp> initializeFirebase() async {
        FirebaseApp firebaseApp = await Firebase.initializeApp();
        return firebaseApp;
      }
    }
  • In main.dart file, modify the return statement in build function to return a FutureBuilder instead of the Material app. FutureBuilder will allow the app the perform asynchronous operations where the function will return a Widget based on the result we get from that operation. In our case, the operation will be the Firebase app initialization which is defined in the FutureBuilder’s future property. If the app is successfully initialized, it will return the Material app. If the initialization fails, it will return a Text to display an error message.

    @override
    Widget build(BuildContext context) {
      return FutureBuilder(
          future: Authentication.initializeFirebase(),
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.done) {
              return MaterialApp(
                title: 'Flutter Firebase Authentication Tutorial',
                debugShowCheckedModeBanner: false,
                theme: ThemeData(
                  primarySwatch: Colors.blue,
                ),
                home: const Signin(),
              );
            }
            return CircularProgressIndicator(
                valueColor: AlwaysStoppedAnimation<Color>(Colors.orange));
          });
    }

Now that we initialized the Firebase app, we can start implementing Firebase Authentication methods in our app.

3. Sign in with Google

Back to the Authentication file we created, we’ll create a method to sign in with Google.

static Future<void> signinWithGoogle({required BuildContext context}) async {
  FirebaseAuth auth = FirebaseAuth.instance;
  GoogleSignIn googleSignIn = GoogleSignIn();

  final GoogleSignInAccount? googleSignInAccount = await googleSignIn.signIn();

  if (googleSignInAccount != null) {
    final GoogleSignInAuthentication googleSignInAuthentication =
        await googleSignInAccount.authentication;

    final AuthCredential credential = GoogleAuthProvider.credential(
      accessToken: googleSignInAuthentication.accessToken,
      idToken: googleSignInAuthentication.idToken
    );

    try {
      final UserCredential userCredential =
          await auth.signInWithCredential(credential);


      Navigator.pushReplacement(
          context,
          MaterialPageRoute(builder: (context) => HomePage()));


    } on FirebaseAuthException catch (e) {
      if (e.code == 'account-exists-with-different-credential') {
        //handle error
        print('account exist with different credential');
      }
      else if (e.code == 'invalid-credential') {
        //handle error
        print('invalid credential');
      }

    } catch (e) {
      //handle error
      print('something else');
    }
  }


}

So, what we’re basically doing here is the following:

  • Create an instance of FirebaseAuth and GoogleSignIn which we’ll later use to authenticate Google user.
  • Use GoogleSignIn instance to call the method signIn which returns a Future<GoogleSignInAccount>. This method we’ll start the sign-in proces by popping a dialog to select a Google account to sign in with which is the returned value.
  • Call googleSignInAccount.authentication to retrieve the authentication token. This token provides us with accessToken and idToken which we’ll use to create the sign in credential
  • Create the authentication credential using GoogleAuthProvider.credential by passing the access token and ID token we got in the previous step
  • Finally call auth.signInWithCredential method and pass the authentication credential we created in the previous step to complete the sign in process

4. Register new user with Email

Let’s first create a signup method in the Authentication class

static void signup(BuildContext context,String email, String password) {
    FirebaseAuth auth = FirebaseAuth.instance;
    auth.createUserWithEmailAndPassword(
        email: email, password: password)
        .then((_) {
      Navigator.of(context).pushReplacement(
          MaterialPageRoute(builder: (context) => VerifyScreen()));
  });



}

In fact, registering a new user using Firebase Authentication is quiet simple. All you need to do is call the method createUserWithEmailAndPassword() and pass the user email and password which will be passed from the Signup page. We’re also passing the context in order to be able to navigate the user to the next screen (Verify screen) which we’ll take about a bit later in this article.

Next, we need to call the method from the Signup page but first we need to get the email and password from the input fields.

First, In Signup page, create two global variables for email and password

late String _email, _password;

Then, add the following code to email and password text fields respectively.

onChanged: (value) {
  setState(() {
    _email = value.trim();
  });
},

 

onChanged: (value) {
    setState(() {
      _password = value.trim();
    });
},

Next, modify the code in the onPressed() property of the Sign up button

onPressed: () {
  //sign up with email
  Authentication.signup(context, _email, _password);

},

4. Send Email verification

Although authentication is an essential part of any app, user verification plays in important part in increasing security too. Now after a user registers a new account, he/she will be redirected to VerifyScreen as you’ve seen in the signup method. What will happen next is that a verification email will be sent to the user and once verification is done, the user can log in to the app and use it.

In the Verifyscreen.dart file, create the following global variables (Class level variables)

final auth = FirebaseAuth.instance;
User? user;
late Timer timer;

Then, let’s  add the following code in the initState() function. initState is the first method that’s called when a screen is built. Here we’ll get the current user’s info and send a verification email. At the same time, a timer will periodically check if the email has been verified and redirect the user to the home page once verification is done.

@override
void initState() {
  user = auth.currentUser;
  user!.sendEmailVerification();

  timer = Timer.periodic(Duration(seconds: 5), (timer) {
    checkEmailVerified();
  });
  super.initState();
}

Create the method checkEmailVerified(). This mwthod will reload the user constantly and check if the user’s verified.

Future<void> checkEmailVerified() async {
  user = auth.currentUser;
  await user!.reload();
  if (user!.emailVerified) {
    timer.cancel();
    Navigator.of(context).pushReplacement(
        MaterialPageRoute(builder: (context) => HomePage()));
  }
}

Now one last thing we need to do here is to ensure closing the timer once the verification process is done. To do that, we’ll close the timer in dispose() method which is, unlike initState() method, the last method in the screen’s lifecycle.

@override
void dispose() {
  timer.cancel();
  super.dispose();
}

 

5. Sign in with email and password

Firebase Authentication provides a built-in method to sign in with email and password which you can implement in very simple steps. Let’s get back to Authentication class and add a new method called signin. This method is very similar to the signup method but instead, we’ll be calling auth.signInWithEmailAndPassword. Again, the email and password will be passed to signin method from Signin page.

static void signin(BuildContext context, String email, String password) {
  final auth = FirebaseAuth.instance;
  auth.signInWithEmailAndPassword(email: email, password: password).then((_) {
    Navigator.of(context).pushReplacement(
      MaterialPageRoute(builder: (context) => HomePage())
    );
  });
}

Then, in Signin page, let’s create a global variables for email and password

late String _email, _password;

Then, assign these variables to the values retrieved from email and password text fields.

onChanged: (value) {
    setState(() {
      _email = value.trim();
    });
},

onChanged: (value) {
    setState(() {
      _password = value.trim();
    });
},

Lastly, let us modify onPressed property of the Sign in Button

onPressed: () {
  Authentication.signin(context, _email, _password);
},

6. Sign out

Let’s create signout method in the Authentication class

static Future<void> signout({required BuildContext context}) async {
  await FirebaseAuth.instance.signOut();
}

Then call that method from HomePage Signout’s button. You’ll notice that I’m surrounding the signout function with a SchedulerBinding and the reason is to ensure that the method within it are executed once build function is finished.

onPressed: () {
  SchedulerBinding.instance.addPostFrameCallback((_) {
    Authentication.signout(context: context);
    Navigator.of(context).pushReplacement(
        MaterialPageRoute(builder: (context) => Signin()));
  });

},

 

7. Keep login state

It’s not necessary to get the user’s credential every time the user opens the app. For example, when the user logs in to the app then closed it, when the user returns to the app, it should automatically sign the user in. For this reason, we’ll implement a checkSignedIn() method in the Authentication class and call it in the initState of Signin page. This method will simply direct the user to the home page if the user is already logged in to the app.

static void checkSignedIn(BuildContext context) {
  Authentication.initializeFirebase();
 
  User? user = FirebaseAuth.instance.currentUser;
  if (user != null) {
    Navigator.of(context).pushReplacement(
        MaterialPageRoute(builder: (context) => HomePage())
    );
  }
}

 

8. Reset password

The last thing to implement is the forgot password feature. This will allow the user to reset their password using their email. In the Authentication class, we’ll add a new method called resetPassword

static void resetPassword(BuildContext context, String email) {
  final auth = FirebaseAuth.instance;
  auth.sendPasswordResetEmail(email: email);
}

When a user clicks on forgot password in the Signin page, he/she will be redirected to the ResetPassword page. From there, ther user is required to enter his/her email and request a password reset. In ResetPassword page, Let’s create a variable for email and assign it to the email textfield input

late String _email;

In the email text field, add the following code

onChanged: (value) {
  setState(() {
    _email = value.trim();
  });
},

Let’s add the following code to onPressed property in Request Password button

onPressed: () {
  Authentication.resetPassword(context, _email);
  Fluttertoast.showToast(
      msg: "A reset email has been sent to you",  // message
      toastLength: Toast.LENGTH_SHORT, // length
      gravity: ToastGravity.CENTER, // location

    timeInSecForIosWeb: 2,
  );
  Navigator.of(context).pop();
},

Conclusion

And there you have it, a complete Flutter Firebase Authentication Tutorial that teaches you everything from A to Z. I hope you enjoyed this tutorial and learnt from it. You can get the complete source code from Github. I have created branches for every step to keep it easier for you to follow.

Wanna learn more about Flutter? I have category called Flutter that’s ripe for you to explore. You can learn about Flutter widgets, layouts, and practice with a bunch of real examples. Also, don’t forget to subscribe to my blog to be one of the firsts to know about my newest posts!

Also, don’t forget to share this post with your friends who are interested in learning about Flutter Firebase auth.

Oh hi there!
It’s nice to meet you.

Sign up to receive awesome content in your inbox, every month.

Let's Do This!

11 thoughts on “Flutter Firebase Authentication Tutorial | Signup and Login

    1. Thanks for your feedback. You’re totally right, I believe there’s always better somewhere. Was there anything that’s hard to follow that made you say that? I’d appreciate it if you can point out what difficulties you faced and how this article can be improved 😊

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top