Flutter web google sign in with Provider state management 2021

Hey there, the goal of this article is to integrate firebase authentication (google sign in) on a flutter website, and on top of that, we want to be able to manage logged in users, so that if a user is logged in into the website he won’t have to sign in every time he uses the url.

Grab a coffe mug and lets start coding…

  • Configure flutter web
  • Create and run flutter web project
  • Packages to use
  • Enable google sign in & cloud firestore
  • Connect flutter project to firebase
  • Get google client id
  • Let’s start coding

Well, on this article I am assuming that you already have flutter installed, the goal is to enable flutter web in to your system, run the following commands to enable flutter web

flutter channel beta

The code above will change your main flutter channel to the beta channel

flutter upgrade
flutter config --enable-web

The code above will upgrade your flutter to the latest version, and then enable web

Well, you create a flutter web project the exact same way you would create any other flutter project, the only difference here is that after the project is created you will see a new directory called web

To run the web app just use flutter run -d chrome command in your terminal.

For this particular project I will be using a pre built flutter web UI, you can go and clone my github repo here, note that this is not mandatory and you can use your own flutter web website.

For this project we will use couple flutter packages, and they are all listed bellow, copy those to your pubspec.yaml file

nb_utils: ^3.3.0+8

provider: ^4.3.2+2

shared_preferences: ^0.5.12+4

firebase_core: ^0.5.3

firebase_auth: ^0.18.3+1

cloud_firestore: ^0.14.3+1

google_sign_in: ^4.5.6

Fist go to firebase and create your project, the process is super straight forward, after creatig your project you will see a windows more or less like this

  1. Enable google sign in

Now we will enable google sign in by going to firebase Build -> Authentication

Now from the different authentication alternatives we will pick google

Now we just have to enable google authentication and set the project support email

Now what we need to do is to enable cloud firestore on Build -> Cloud firestore

Make sure you select the test mode on cloud firestore

Now going back to the project overview page we will add the web app to our firebase project

Pick a name for the project, and register app

The final stage here is to copy the following code into the web/index.html file in our flutter project

Make sure you add these two html tags to the bottom of the html file

<script src="https://www.gstatic.com/firebasejs/7.17.1/firebase-firestore.js"></script><script src="https://www.gstatic.com/firebasejs/7.8.0/firebase-auth.js"></script>

We are almost there, now we just need to get the google client id and add that to our flutter project, just open Google cloud platform, one you login into the google cloud dashboard, make sure ro select the correct firebase project that you are working on

After that you just have to click on credentials — Oauth 2.0 client id — web client

And the final step here is to copy the following tag to the <head></head> section of the index.html file in the flutter project

<meta name="google-signin-client_id" content="YOUR-CLIENT-KEY-HERE">

Now it’s that time, let’s start with the fun stuff…

  1. Creating a helper file

Now inside the lib forder, we will create another folder called helper, and inside the helper create a file called constants.dart, that will contain values that will be constant in the app and will be required by more than one file.

initialization will be used to initialize the firebase app, firebaseFirestore, will contain an instance of firebase firestore, and auth an instance of Firebase authentication.

2. Creating user model

Modeling data is essential when we are dealing with data from a database, and it reduces the chance of making mistakes while building the project, so now we will create a user model, to interact with user data on cloud firestore, create a inside the lib folder create the file models/user.dart

So here we have a class called UserModel the static contants represent the field names on the cloud firestore, then we have some private variables that will be initialized with the values of the respective fields on firebase, we created some getters to access the value of the private varibles outside the UserModel class, and finally we have a named constructured UserModel.fromSapshot that will initialize the private variables

3. Creating user services

Now we will create some services, services are used to directly interact with the database (firebase in our case), so lets create the user’s services.

The first thing we want to ensure, is that a new user can create an account, so let’s create services/user.dart file

Now we need another two methods, one to check if the user exists and another to retrive a user using the user id

4. Creating providers

Providers work as middle ground, between the app services and the application UI, so here we wish to connect the app services with UI, lets start by creating a file names providers/auth.dart to take care of the user authentication

Status enum, will be used to keep track of the user authentication status, and the AuthProvider class is a mixin of ChangeNotifier, we defined inside the AuthProvider all class properties that we will need, not we need to defined a named constructor

What the _fireSetUp() method does, is basically listening to user authentication changes on firebase and run some code base on the results.

Now, lets write a function to authenticate users with google, this will be a little bit long function, but worry not

Fom the lines 3 to 9, we are just defining variables, we need AuthCredential to authenticate using GoogleAuthProvider,

await auth.signInWithCredential(credential) will return an object of the type user model, on line 13, we create a shared preferece key id, where the value is the user id, from 14 to 18, we check if the user already exists on cloud firestore, and if he doest we create a new user in tthe data base, then we initialize the user model i ou app, else if the user exists already we will just initialize the user model, then we return the result.

Let’s see how the user model is initialized

And after the user is sign in, he needs to be able to sign out, and this is how its done

do you remember the _onStateChanged() method created at the beginning of the file? This is how it works

Basically, if the User returned by firebase is null, it means that the app user is unauthenticated, and if its not null, means that the user exists and is currently authenticated

This is the final file

Now we need another provider, called app provider, that will change its state if there’s a process being undertaken inside of the app, inside the providers folder create another file called app.dart

5. Configuring main.dart

Inside main.dart file, we will need to register the providers we just created, and do some other configurations such as initializing firebase app, and setting a screen controller, which is basically a widget that will return the correct widgets based on the users authentication status

And here is the code for the app screen controller widget

The switch() statement will keep track of the user auth status, and return different widgets based on status changes.

The final file will look like this

6. Final step

Now what we need to do, is calling the methods we defined inside the providers from the UI widgets, not that provider variables must be initialized inside of the build method of the widget on which they will be used, so that they can make use of the widget’s context, if you are using the starting templated provided at the beginning of this article go to the screens/authentication.dart file, define the following variables in side the build method.

final AuthProvider authProvider = Provider.of<AuthProvider>(context);final AppProvider appProvider = Provider.of<AppProvider>(context);

And place the following code inside, onTap, property of the gesture detector

The final file should look like this

And there you go! I hope this article was helpful, make sure to check ou the complete code at the repo

Flutter developer & ML enthusiast