Flutter: Implementing Google Sign In
Firebase Authentication provides backend services, easy-to-use SDKs, and ready-made UI libraries to authenticate users to your app. It supports authentication using passwords, phone numbers, popular federated identity providers like Google, Facebook and Twitter, and more.
In this article, I will be showing how to set up the Flutter app and implement Google sign-in using Firebase authentication.
NOTE: This article has been updated to the latest Flutter 2.0 stable release, with null safety enabled, for creating the sample app.
In this article we will cover the following topics:
- Create a new Flutter project with null safety
- Create a new Firebase project
- Set up Firebase for Android, IOS & Web
- Configure Firebase Authentication
- User auto-login
- Configure Firebase on Codemagic (CI/CD for Flutter)
So let’s get started.
Project overview
The app layouts will be simple having just two screens, the initial screen will be a sign in screen (where users can sign in using their Google account), and the next screen will user info screen (displaying some of the user information retrieved from one’s Google account) with a button for signing out.
The project directory structure will be as follows:
Getting started
We will start by creating a new Flutter project with the latest version of Flutter 2 and migrate it to null safety. Then, we will add the required packages and assets to the project.
Create a new Flutter project
Open Terminal or use the terminal in your code editor. Navigate to the folder where you want to create the project and use the following command:
flutter create flutterfire_samples
Then open the project using your favorite code editor. For opening with VS Code you can use:
code flutterfire_samples
Flutter 2.0 has support for null safety in the stable channel, but in order to use it inside the app, you have to run a command for migrating the project to null safety.
Before running the migration command, check if all your current project dependencies support null safety by using:
dart pub outdated --mode=null-safety
Then, run the following command to migrate:
dart migrate
You can follow the migration guide here.
Plugins
The plugins needed for this project are:
- firebase_core: for initializing Firebase
- firebase_auth: for implementing Firebase authentication
- google_sign_in: to use Google Sign-In
You will need to include the
firebase_core
plugin for using any other firebase related plugins as it is used for initializing theFirebaseApp()
.
You can import the packages to your Flutter project by adding them to your pubspec.yaml
file:
Save it to run flutter packages get
.
Assets
You will be needing two images while building the UI of this sample app.
You can get the image from here.
Create a new folder called assets
in your project directory and insert the two images ( google_logo.png
& firebase_logo.png
) that you downloaded.
Now, import the assets
folder in your pubspec.yaml
file.
Set up Firebase project
To start using Firebase with the application, you first have to create a new Firebase project. Follow the steps below:
- Create a new Firebase project by going to the Firebase console.
- Click on Add project.
- Enter a Project name and click on Continue.
- Next, you will be asked whether you want to enable Google Analytics for the project. We won’t be needing analytics as this is just a sample project. Click on Create project.
If you want to enable Google Analytics anyway, then you will be prompted to select a Google Analytics account on the next screen:
Wait for the project to be created, and you will be navigated to the Firebase dashboard of the project.
Platform configurations
Now, we have to complete the platform-specific Firebase configurations. Though we are using Flutter (which is a cross-platform framework), but we still have to integrate the Firebase project separately for each platform. Flutter 2.0 has support for Android, iOS, and Web in its stable channel, so we will be configuring for all three platforms.
Android setup
First of all, let’s configure for the Android platform.
- Select the Android icon from the Firebase dashboard.
- Enter the Android package name, an app nickname, and the SHA-1. Click on Register app.
- Download the
google-services.json
file, and place it in the android -> app directory. Click on Next.
- Just follow the instructions, and add the required code snippets to your project. Click on Next.
You have successfully configured Firebase for Android. On the final step, click on Continue to console to go back to the dashboard.
iOS setup
- Select the iOS icon on the dashboard.
- Enter your iOS bundle ID and an app nickname. Click on Register app.
- Download the
GoogleService-Info.plist
file. Click on Next.
- Go back to your project, open the
ios
folder using Xcode, and drag and drop the file that you downloaded into the Runner subfolder. When a dialog box appears, make sure that Runner is selected in the “Add to targets” box. Then click Finish. - You can skip steps 3 and 4, as they are automatically configured by the Flutter Firebase plugin that we will be adding soon. Click on Continue to console to go back to the dashboard.
Web setup
- Select the Web icon on the dashboard.
- Enter the App nickname, and click on Register app.
- Now, add the code snippets for integrating the Firebase SDK into the web app.
Then, click on Continue to console to navigate back to the dashboard.
Finally, you have completed the Firebase configuration for all three platforms.
Set up Authentication
In order to use Google Sign-In with Firebase Authentication, you have to enable it by going to the Authentication page from the left menu of the Firebase dashboard, select the Sign-in method tab.
Here, enable Google (under Provider), enter project name and support email, and click on Save.
Make sure you also add the support email in the Firebase project settings -> General.
For using Google Sign-In on Android device there is no extra configuration required. But for using it on iOS device, you have to just one more thing.
Go to your project directory -> ios -> Runner -> Info.plist file, add the following there:
Don’t forget to replace the value as per the above comment with the
REVERSED_CLIENT_ID
present in theGoogleService-Info.plist
file.
Initialize Firebase
As we have configured the project for using Google Sign-In with Firebase Authentication. we can start defining methods for the authentication logic.
Create a new file called authentication.dart
inside the folder lib -> utils. To use any other Firebase service, we have to first initialize the FirebaseApp
:
In the above code, we have initialized Firebase inside the initializeFirebase()
method. Later, we will add the logic for auto-login here.
Implement Google Sign-In
Now, let’s add the method for Google Sign-In:
Here, we can handle the error more elegantly by showing a SnackBar
(if you have noticed, that's why we have passed the BuildContext
to this method). The try-catch
block can be modified to this:
The customSnackBar()
method looks like this:
The signInWithGoogle()
method that we have defined, will help to authenticate a user with Google Sign-In on the Android & iOS platforms. But in order to use Google Sign-In on Web, you have to modify it to the following:
On the web platform, you have to use the signInWithPopup()
method on the FirebaseAuth
instance.
Sign-out method
The sign out method is quite simple to implement, but on the Web platform you do not need to call the googleSignIn.signOut()
method (it would result in an error), just calling FirebaseAuth.instance.signOut()
will do the job.
Building the UI
Just delete everything from the main.dart
file and paste the boilerplate code given below.
Let’s build the UI for SignInScreen
.
SignInScreen layout
Create a new dart file called sign_in_screen.dart
inside the directory lib -> screens.
The SignInScreen
layout would look like this:
SignInScreen
should be a Stateful Widget because we will be making some changes to the UI later which will need the widgets to be redrawn.
The code for SignInScreen
UI will be like this:
In the above code, you will notice a FutureBuilder
where we are waiting for the Firebase it get initialized before showing the GoogleSignInButton
widget.
Now we have to design the Sign in with Google button. Create a new file called google_sign_in_button.dart
inside the directory lib -> widgets.
It will be a StatefulWidget
and will contain a method call to the Google Sign-In authentication inside the onPressed()
method.
We haven’t filled the onPressed()
method in the above code, let's add the authentication method call:
If the authentication successfully returns the user, then this will navigate to the UserInfoScreen
and pass the retrieved user to it.
UserInfoScreen layout
Create a new dart file called user_info_screen.dart
inside the directory lib → screens.
The UserInfoScreen
layout would look like this:
The UserInfoScreen
should be a Stateful Widget where some user info will be shown along with a Sign Out button.
Here, Authentication.signOut()
method, that we defined earlier, is used for signing out a user.
The _routeToSignInScreen()
method is just used to show a slide transition animation (from left to right) while navigating back from the UserInfoScreen
to the SignInScreen
as the user signs out of the account.
We have almost completed the app, there is just one more thing to be discussed.
Auto login
If a user has logged in to the app, and then closed it, so as the user comes back to the app it should automatically sign in (that is, without taking credentials every time someone returns back).
For implementing this, we just have to complete the TODO
, that we left before, in the initializeFirebase()
method. The modified method will be this:
Configure Firebase on Codemagic
In our local configuration, we have downloaded the google-services.json
and GoogleService-Info.plist
files and kept it in the android
& ios
directory of the Flutter app respectively. These files contain sensitive data, like the API key and information about the app. These files shouldn't be checked into version control or exposed to the world. We have to take certain steps to secure our sensitive data.
Ignore the files in the version control system
First of all, we have to list the two private files, google-services.json
(present in the folder android/app/
) and GoogleService-Info.plist
(present in the folder ios/Runner/
) in the .gitignore
file, to avoid them being checked into version control, such as Git.
Once you have added the two files into .gitignore
, commit the .gitignore
file.
Encode the files
At this stage, we have ensured that we won’t commit the sensitive files to the version control system. However, the continuous integration server will expect to find this file in order to successfully build the Flutter app.
To encode the files, in the Configuration as code section of the Flutter project you can go to the Encrypt environment variables option.
Then just drag and drop the files you want to encrypt, it will generate an encrypted string.
Copy the generated string, add that to the Environment variables section of the project.
Adding the environment variable in Codemagic
- Expand the Environment variables tab.
2. Add the two encrypted strings generated from the terminal as:
ANDROID_FIREBASE_SECRET
(Variable name) -> encoded string fromgoogle-services.json
(Variable value)IOS_FIREBASE_SECRET
(Variable name) -> encoded string fromGoogleService-Info.plist
(Variable value)
3. Click on Save changes.
Adding a pre-build script
- In the Codemagic project settings, click on the + button before the Build stage.
2. Add the following to the Pre-build script.
#!/bin/sh
echo $ANDROID_FIREBASE_SECRET | base64 --decode > $FCI_BUILD_DIR/android/app/google-services.json
echo "Listing android Directory to confirm the google-services.json is there! "
ls android/app/
echo $IOS_FIREBASE_SECRET | base64 --decode > $FCI_BUILD_DIR/ios/Runner/GoogleService-Info.plist
echo "\nListing iOS Directory to confirm the GoogleService-Info.plist is there! "
ls ios/Runner/
3. Click on Save changes.
Start building
Click the Start new build button to start the build process.
While the build process is running, you can click the Pre-build tab to see the output of the code we added to the pre-build script. You can see that both files, google-services.json
and GoogleService-Info.plist
, are present, although we did not add them to the version control system. They are generated from the encoded strings.
After the build is finished successfully, you can also download the artifacts to test them on a real device.
If you want to generate a release build of your app, then check out the following articles:
Dependency caching
Firebase dependencies take longer to build, in order to prevent this you can use dependency caching on Codemagic to lower the build time.
To cache your Gradle and CocoaPods, enable dependency caching and include the following two paths to the Dependency caching section in your Codemagic project settings:
$HOME/.gradle/caches
$HOME/Library/Caches/CocoaPods
Conclusion
The FlutterFire Authentication app is now complete, and we have successfully tested it with Codemagic by setting up Firebase with encoded files. I hope that you found some useful information in this article.
This article is also available on Codemagic Blog.
You can find the GitHub repo for this project here:
If you like this project, please give “Star” (⭐️) to my GitHub repo.
Check out my other articles
If you want to support me and want me to continue writing Flutter articles and building some interesting Flutter projects, please contribute to my Patreon page below:
You can follow me on Twitter and find some of my projects on GitHub. Also, don’t forget to checkout my Website. Thank you for reading, if you enjoyed the article make sure to show me some love by hitting that clap (👏) button!
Happy coding…
Souvik Biswas