Step By Step Guide On How to Authenticate your Flutter App with FireBase Auth

dav4thevid

Fabusuyi David Oluwasegun

Posted on December 17, 2020

Step By Step Guide On How to Authenticate your Flutter App with FireBase Auth

In this post, I will be walking you through how to authenticate your flutter app with firebase. we won't be building anything fancy. just a demo app with three screens (Sign-Up, Sign-In and Homepage). This post assumes you've already setup your IDE with Flutter, we won't do that here, if you ready, Lets dive right in.

TLDR
If you already familiar with Flutter and Firebase and this post is too long for you to read, you can download the final project we would be building here on github

If you are not fully familiar with Flutter and Firebase, I would highly recommend you read through or better still code along so as to fully understand how things work.

Firstly let create our Flutter App.

if you are using VSCode, Open the Command Palette ( Ctrl + Shift + P) for windows and ( Cmd + Shift + P) for mac. click on New Project and feel free give the project any name you want. (Note: all letters has to be lower case). If you are using Android Studio as your IDE. click on file, then navigate to new flutter project. select flutter application then name the project and choose any folder path you want your project to be saved in. set package name is your app domain name, if you don't have that feel free to add this (com.example.yourappname) P.S: Write this down, we would be need it when we are ready to initialize our app with firebase, also Don't forget to tick all boxes then click finish.

Lets start creating our screens.

(Note: I would be using VSCode for this article, if you're using Android Studio you can click the play button to run your app.)
open your terminal then navigate to your newly created flutter project then run your app with flutter run. open lib/main.dart file and delete MyHomePage class, we would be creating ours shortly. Create a new folder, I will name mine screens. Now click on new file and name the file SignUp.dart, do same for SignIn.dart and Homepage.dart respectively.

Open our newly created SignUp.dart file import material Design with import 'package:flutter/material.dart' then create your signup class (Stateless Widget), you can do that by just typing stl an auto create would popup, just click it (there you go πŸ˜‰). Name it signup class, lets make the class return a text widget with "Sign Up" text temporarily, while we create our routes. Your SignUp class should look like this.

import 'package:flutter/material.dart';

class SignUpScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Text('Sign Up'),
    );
  }
}


Enter fullscreen mode Exit fullscreen mode

feel free to do the same for SignIn and Homepage files.

Open the main.dart file, you would notice the myHomePage class we deleted is already prompting us of an error, delete the entire line. we would be creating ours shortly. Now add this initialRoute: SignUp.id.
Note: we could use any of this Material App properties (home or initialRoute) as our base route, but I prefer using initial route so as to make the naming convention the same, its doesn't really matter in our case, you could use either of the two.
PS: home takes a widget as its property, while initialRoute takes a string. Notice that its prompt an error, that is because we have not added the route to our SignUp class. Open SignUp and add this line static String id = 'sign-up';, Do the same for both SignInScreen and HomepageScreen.

We've added our initial route, Our app would navigate to signup screen upon launch. Now lets create our routes, this takes Map as argument. now add this lines SignUpScreen.id: (context) => SignUpScreen(), Do same for both SignIn and Homepage route.
Your code should now look like this.

import 'package:flutter/material.dart';
import 'package:flutter_practice/Screens/Homepage.dart';
import 'package:flutter_practice/Screens/SignIn.dart';
import 'package:flutter_practice/Screens/SignUp.dart';


void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      // home: SignUpScreen(),
      initialRoute: SignUpScreen.id,
      routes: {
        SignUpScreen.id: (context) => SignUpScreen(),
        SignInScreen.id: (context) => SignInScreen(),
        HomepageScreen.id: (context) => HomepageScreen(),
      },
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

Now hot restart you your app with capslock R. You should see a black screen with a huge 'Sign Up' red text, (😞 Our screen is ugly, lets style it up a little). Im not going to walk through the styling process just copy and paste the below code, if you are following along.

import 'package:flutter/material.dart';

class SignUpScreen extends StatelessWidget {
  static String id = 'sign-up';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.lightBlueAccent,
      body: Container(
        child: Center(
          child: Padding(
            padding: const EdgeInsets.all(50.0),
            child:
                Column(mainAxisAlignment: MainAxisAlignment.center, children: [
              Text(
                'Sign Up Here',
                style: TextStyle(fontSize: 30, color: Colors.white),
              ),
              SizedBox(
                height: 20,
              ),
              TextFormField(
                obscureText: true,
                style: TextStyle(color: Colors.white),
                decoration: InputDecoration(
                  labelText: 'Email',
                  icon: Icon(
                    Icons.mail,
                    color: Colors.white,
                  ),
                  errorStyle: TextStyle(color: Colors.white),
                  labelStyle: TextStyle(color: Colors.white),
                  hintStyle: TextStyle(color: Colors.white),
                  focusedBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: Colors.white),
                  ),
                  enabledBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: Colors.white),
                  ),
                  errorBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: Colors.white),
                  ),
                ),
              ),
              TextFormField(
                style: TextStyle(color: Colors.white),
                decoration: InputDecoration(
                  labelText: 'Password',
                  icon: Icon(
                    Icons.lock,
                    color: Colors.white,
                  ),
                  errorStyle: TextStyle(color: Colors.white),
                  labelStyle: TextStyle(color: Colors.white),
                  hintStyle: TextStyle(color: Colors.white),
                  focusedBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: Colors.white),
                  ),
                  enabledBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: Colors.white),
                  ),
                  errorBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: Colors.white),
                  ),
                ),
              ),
              RaisedButton(
                onPressed: () {},
                child: Text(
                  'Submit',
                  style: TextStyle(fontSize: 18),
                ),
              )
            ]),
          ),
        ),
      ),
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

You can replicate that for the Signin screen as well, but if you like, feel free to style it to your own taste. We now have our auth screens styled up, we can now initialize our app with Firebase. Our SignUp Screen should look like this Sign up screen

Initializing App to Firebase

visit the firbase console here.
P.S: You need to have a google account, SignUp if you don't have one.
click on Add Project, enter the project name, then create new project, this should take less than 20seconds.( We would be building for Android on this post). incase you forgot your package name, open android/app/build.gradle scroll downwards you would see applicationId thats you package name, Now click continue and download your google.services.json file.
P.S: Make sure to click the download button just once, so as to prevent duplicate files been downloaded, if you've download this particular file before, delete it from your downloads folder. Now move the google.services.json file you just downloaded into android/app root folder. make sure its the right folder, if not its might prevent our app from running.

Once you've done click on next then open android/build.gradle and add this line under dependencies classpath 'com.google.gms:google-services:4.3.4' and this google() under all project repositories if its not already added. Now open android/app/build.gradle. and add this line apply plugin: 'com.google.gms.google-services' under app plugin then this implementation 'com.google.firebase:firebase-analytics' under dependencies. (😫phew!! we are almost there).

We need to install some Firebase packages into our app namely firebase_auth and firebase_core. open pubspect.yaml file and add this lines firebase_auth: ^0.18.0+1 and firebase_core: ^0.5.0, make sure its properly aligned (pubspect.yaml could be funny at times, lolx).Once you've done that, click on Get Packages this should install these packages into our app.

Now open main.dart file and add this lines.
WidgetsFlutterBinding.ensureInitialized();
and await Firebase.initializeApp();.

Your main.dart file should now look like this

void main() async{
   WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}
Enter fullscreen mode Exit fullscreen mode

P.S: don't forget to import package:firebase_core/firebase_core.dart;

Close and rerun your app on the terminal, ctrl c and flutter run. If your app runs successfully, Congratulations!!! you have successfully initialized your flutter app with firebase.

if you encounter build errors. click here for fix.

Now that we've successfully created our screens and initialized our app with flutter, its time we start writing our authentication logic.

Authenticating our App with Flutter.

Open the SignUp file, since we using TextFormField we would have to wrap our entire column into a form widget. click the column widget and also click the yellow lightbulb that shows at the left side, select wrap with widget, then rename widget to Form.

Form has a property called key add this key: _formKey. This creates a container for form fields and make us get the form values upon save. We would have to create an instance for GlobalKey, which is the _formKey we added. add this line below our static id String final _formKey = GlobalKey<FormState>();. Now create create email, password variable. String _email; String _password;. We now have to add a call back inside our TextFormField to bind our email and password variable inside our callback. Add this line inside our TextFormField

onSaved: (emailValue) {
    _email = emailValue;
  },
Enter fullscreen mode Exit fullscreen mode


Do same for password TextFormField. Now lets test and see if our binding works correctly. Inside our RaisedButton add this line.

 onPressed: () {
     _formKey.currentState.save();
     print(_email);
     print(_password);
   },
Enter fullscreen mode Exit fullscreen mode

Type in a dummy email and password inside the text field and click submit, you should see the text you typed inside your terminal. Lets move on.

Now add this line inside the onPressed callback

onPressed: () async {
      _formKey.currentState.save();
      try {
    final new_user = await _auth.createUserWithEmailAndPassword(
    email: _email, password: _password);
    if (new_user != null) {
    Navigator.pushNamed(context, HomepageScreen.id);
             }
      } catch (e) {
         print(e);
       }
    },
Enter fullscreen mode Exit fullscreen mode

The above code takes our _auth instance from firebase and pass our email and password values into the createUserWithEmailAndPassword function from firebase. its also check if user is not available, if so its navigate us to the homescreen page. if there is an error, its catches the error and print it on the terminal.

We have to enable email and password authentication from firebase console

Now visit the firebase console here then click on your project, on the left, click on authentication, click on sign in methods, You can see Email/Password is disabled. enable it and save.

Before we test, lets go to our Homepage screen and add some contents to it, so its doesn't show a complete blank screen. Inside the Homepage screen, delete the entire class and add this


class HomepageScreen extends StatelessWidget {
  static String id = 'homepage';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: null,
        actions: <Widget>[
          IconButton(
              icon: Icon(Icons.close),
              onPressed: () {
              }),
        ],
        title: Text(
          'Homepage',
          style: TextStyle(color: Colors.white),
        ),
        backgroundColor: Colors.lightBlueAccent,
      ),
      body: Center(child: Text('Homepage'),),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Open terminal and run hot restart. Now test sign up, its should sign the user up and navigate to Homepage Screen. You can click on users on firebase console, to see the list of registered users.
P.S: When testing make sure your password is 6 characters or above, firebase won't accept anything lower than that.

Lets implement signOut on our app.

Inside the method in our IconButton widget, add this
_auth.signOut();
Navigator.pop(context);
. also import firebase auth import 'package:firebase_auth/firebase_auth.dart'; and create its instance like so final _auth = FirebaseAuth.instance; . Your Homepage screen should now look like this.

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';

class HomepageScreen extends StatelessWidget {
  static String id = 'homepage';
  final _auth = FirebaseAuth.instance;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: null,
        actions: <Widget>[
          IconButton(
              icon: Icon(Icons.close),
              onPressed: () {
                // Implement logout functionality
                _auth.signOut();
                Navigator.pop(context);
              }),
        ],
        title: Text(
          'Homepage',
          style: TextStyle(color: Colors.white),
        ),
        backgroundColor: Colors.lightBlueAccent,
      ),
      body: Center(child: Text('Homepage')),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Now run hot reload r and test the log out functionality. its should take you back to the SignUp Screen. We are almost there, lets implement the SignIn functionality

Underneath the RaisedButton create a FlatButton and give it Text widget like so.

FlatButton(
    onPressed: () {
    Navigator.pushNamed(context, SignInScreen.id);
},
     child: Text('Sign In'),
    )
Enter fullscreen mode Exit fullscreen mode

The navigator.pushNamed line would make our app navigate to the Sign In Screen. Now test and see if its working.

Open the SignIn Screen and wrap the column widget with a form widget add the key property also. Create an email and password variable like we did when implementing the Sign Up functionality, I wont walk through that again, you can check the SignUp Screen or scroll up for reference.

Inside the onPressed callback in our RaisedButton add this line

  onPressed: () async{
_formKey.currentState.save();
   try {
      final user = await _auth.signInWithEmailAndPassword(
      email: _email, password: _password);
      if (user != null) {
      Navigator.pushNamed(context, HomepageScreen.id);
       }

       } catch (e) {
        print(e);
      }
   },
Enter fullscreen mode Exit fullscreen mode

This should navigate you into HomepageScreen, if you entered your correct credentials. (phew 😌! Finally, haha). We have successfully authentication our app with firebase auth. Congratulations!!!.

Feel free to correct me if you spot any errors, you can also checkout my future posts where I would be walking you through how to add forget password, reset password with firebase.

Your feedbacks and comments would be greatly appreciated. Thanks for your time.

πŸ’– πŸ’ͺ πŸ™… 🚩
dav4thevid
Fabusuyi David Oluwasegun

Posted on December 17, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related