Add Google Sign In to Flutter using Firebase

Let's learn how to add google sign-in to your flutter multiplatform project.

Add Google Sign In to Flutter using Firebase

Flutter is a Google's UI Toolkit for Crossplatform Application Development. As of now, there is no single package to add Google oAuth to your Flutter Application. In this blog, we will see how we set up Google Authentication in our Padasalai app for Android, iOS, Web, Windows, and macOS.

Firebase Project Setup.

The first step is to enable Google Authentication in your Firebase Console. Go to the sign-in method section of authentication. Here enable Google as a sign-in provider.

Enable Google Sign In.png

Also, you may need to add a Redirect URL and get Google sign-in Client ID in your Google Cloud project.

  • Go to the Google Cloud Platform Console and select your project
  • Go to APIs & Service -> Credentials
  • Create new credentials for your app by selecting CREATE CREDENTIALS and then OAuth client ID
  • Select Other as the Application type, give it a name (eg. Desktop), and then click Create.

Flutter Project Setup

Configure Firebase in Project

Configuring Firebase is much easier with the help of flutterfire_cli in Flutter.

For iOS and macOS go to their respective folders root-project\ios\Runner\Info.plist and add following configurations.

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleTypeRole</key>
        <string>Editor</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>#REVERSED_CLIENT_ID</string>
        </array>
    </dict>
</array>

Here #REVERSED_CLIENT_ID can be gotten from the GoogleService-Info.plist file.

For macOS, We need to add extra network configuration things in macOS\Runner\DebugProfile.entitlements and Release.entitlements.

    <key>com.apple.security.network.client</key>
    <true/>
    <key>com.apple.security.network.server</key>
    <true/>

Install Packages.

Now we need to add the following packages in pubspec.yaml. These packages are required to add google sign-in in our app.

  desktop_webview_auth: ^0.0.9
  firebase_auth: ^3.6.4
  firebase_auth_desktop: ^1.0.2
  firebase_core: ^1.21.0
  firebase_core_desktop: ^1.0.2
  google_sign_in: ^5.4.1
  google_sign_in_dartio: ^0.2.1

Oh Yeah! that's a lot. Here firebase_auth_desktop, firebase_core_desktop, desktop_webview_auth, google_sign_in_dartio these all are desktop specific packages.

Setup Google Sign In client ID.

Since Firebase doesn't support desktop apps right now, we need to use GoogleSignInDart to register the Google clients.

if (!kIsWeb && (Platform.isWindows || Platform.isMacOS)) {
      await GoogleSignInDart.register(
        clientId: #YOUR_GOOGLE_CLIENT_ID,
      );
}

We checked that is it not web before calling Platform to prevent an Unimplemented error.

Initialize Firebase.

Now firebase initialize it in the main function.

  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

Auth Service

To handle the authentication logic, let's Create a class called Auth Service. In that create an instance of both FirebaseAuth and GoogleSignIn.

class AuthServices {

  final FirebaseAuth firebaseAuth = FirebaseAuth.instance;

  final GoogleSignIn googleSignIn = GoogleSignIn();

}

Sign In

We need to handle Sign In in different methods for each platform. For the web, we are going to use the signInWithPopup method. In this method, it will create a Pop-up window for Google Sign In.

      GoogleAuthProvider authProvider = GoogleAuthProvider();
      await firebaseAuth.signInWithPopup(authProvider);

For Windows and macOS, we are going to use the signIn method provided by DesktopWebviewAuth. This is similar to the web but the Webview container will be created inside our app. In Windows, The Desktop WebView plugin uses the Edge WebView2 to generate a WebView window.

      final authResult= await DesktopWebviewAuth.signIn(
        GoogleSignInArgs(
          clientId: #YOUR_GOOGLE_CLIENT_ID,
          redirectUri: #YOUR_REDIRECT_URL,
          scope: signInScope,
        ),
      );

      /// Create a new Google Auth Credential
      final credential = GoogleAuthProvider.credential(
        idToken: authResult?.idToken,
        accessToken: authResult?.accessToken,
      );

      /// Sign in with google auth credential.
      await firebaseAuth.signInWithCredential(credential);

Here signInScope is https://www.googleapis.com/auth/userinfo.email to get the user's email address detail. Most of the time the redirect URL will be https://#YOUR_PROJECT_ID.firebaseapp.com/__/auth/handler (You may need to set this up in Google Cloud Console).

Now for mobiles. We don't need to configure anything special for android apps. However please make sure google-services.json for android and GoogleService-Info.plist for Apple platforms are present. If not download the google-services.json configuration file for Android from the Firebase console and place it in project-root\android\app. For Apple platforms, it's recommended to not configure manually. Just download GoogleService-Info.plist from the Firebase console. Open the iOS and macOS directory of the Flutter project in Xcode. In the left side panel right click on the Runner directory then Add Files to Runner and select the respective plist file.

    final GoogleSignInAccount? googleAcc = await _googleSignIn.signIn();
    final GoogleSignInAuthentication googleAuth =
        await googleAcc!.authentication;

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

    await firebaseAuth.signInWithCredential(await credential);

Sign Out

Now let's go to the sign-out part. It's very simple you all just need to do is calling the signOut method in Google Sign In instance and Firebase Auth instance.

    await googleSignIn.signOut();
    await firebaseAuth.signOut();

Here is the Whole Auth Service class

import 'dart:async';
import 'dart:io';

import 'package:desktop_webview_auth/desktop_webview_auth.dart';
import 'package:desktop_webview_auth/google.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart';
import 'package:google_sign_in/google_sign_in.dart';

class AuthServices {

  final FirebaseAuth firebaseAuth = FirebaseAuth.instance;

  final GoogleSignIn googleSignIn = GoogleSignIn();

  Future<User?> signInWithGoogle() async {

    late UserCredential userCredential;

    if (kIsWeb) {
      GoogleAuthProvider authProvider = GoogleAuthProvider();
      userCredential = await firebaseAuth.signInWithPopup(authProvider);
    } else if (Platform.isWindows || Platform.isMacOS) {
      final authResult = await DesktopWebviewAuth.signIn(
        GoogleSignInArgs(
          clientId: googleClientId,
          redirectUri: redirectUrl,
          scope: signInScope,
        ),
      );
      /// Create a new Google Auth Credential
      final credential = GoogleAuthProvider.credential(
        idToken: authResult?.idToken,
        accessToken: authResult?.accessToken,
      );
      /// Sign in with google auth credential.
      userCredential = await firebaseAuth.signInWithCredential(credential);
    } else {
      userCredential =
          await firebaseAuth.signInWithCredential(await getAuthCredential());
    }
    return userCredential.user;
  }

  Future<AuthCredential> getAuthCredential() async {
    final GoogleSignInAccount? googleAcc = await googleSignIn.signIn();
    final GoogleSignInAuthentication googleAuth =
        await googleAcc!.authentication;

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

    return credential;
  }

  Future<void> signOut() async {
    await googleSignIn.signOut();
    await firebaseAuth.signOut();
  }

}

Now you can call this from your button's onPressed() method

AuthService().signInWithGoogle().then((user) {

    if (user != null) {
      // Process to next step.
    } else {
      // Handle Sign In Failure
    }

}

P.s. Make sure you added your machine debug SHA fingerprint in the Firebase console to prevent sign-in call rejections.

That's it. Easy Peasy.

Who we are

RedLeaf Softs Pvt. Ltd. is an IT Company Based in Thoothukudi. We provide Mobile application development and cross-platform development services.

Learn More about us.

Get 15 minutes Free Consultation on how to get your idea to Real World.