Skip to main content

Command Palette

Search for a command to run...

How to Implement User Authentication in Flutter Using Google OAuth

Updated
7 min read
How to Implement User Authentication in Flutter Using Google OAuth
B
  • I am a Flutter developer with a passion for making beautiful and intuitive apps for mobile and the web.

  • I'm also a Google-certified UX designer.

  • I freelance part-time as a tech writer on Upwork.

Introduction

User authentication is a crucial aspect of modern app development, and integrating OAuth in your Flutter app can simplify the authentication process while providing a seamless login experience for users.

In this in-depth guide, we'll explore how to implement OAuth in Flutter using Firebase. By leveraging the power of Firebase, we can streamline the authentication process, enabling users to sign in with just their Google account. Let's dive into the step-by-step process.

What is OAuth: A little background

Before diving deeper into the implementation, it's essential to understand the OAuth flow and how it works in conjunction with Firebase Authentication.

  • OAuth, "Open Authorization," is an open standard for authorization that allows users to grant access to their information to third-party applications without sharing their credentials (e.g., username and password).

  • Firebase Authentication supports OAuth providers like Google, Facebook, Twitter, and more. It handles the authentication flow, token exchange, and user profile retrieval.

How to Implement Google Sign-in Method in Flutter

With Google Sign-In, users can quickly log in using their Google credentials, eliminating the need to remember yet another username and password. Below are the steps to set this up in your Flutter app.

#1. Setting up the Development Environment

To get started with Firebase OAuth in your Flutter app, you'll need to set up your development environment:

  • Install the Flutter SDK and set up your preferred IDE, such as Visual Studio Code or Android Studio. In this tutorial, I will be using Android Studio.

  • Create a new Flutter project from a terminal using the Flutter CLI command flutter create or use the Android Studio UI.

#2. Setting up Firebase

We need to configure Firebase for our Flutter app by creating a new project in the Firebase console and adding the necessary Firebase configuration files to the app.

Fig.1: Creating a new Firebase project

Fig.1: Creating a new Firebase project

Firebase supports several platforms, but the great thing is that integration into your app is easy. Since we are building a Flutter app, we will select the Flutter icon from the list.

Fig.2: Selecting a platform

Next, a list of steps guiding you through the process appears.

Fig.3: Adding Firebase to a local project

The Firebase CLI provides a number of tools to manage and deploy to Firebase projects from our terminal, we will need to install it to use the FlutterFire CLI which enables working with Flutter.

  • Install the Firebase CLI using npm:
npm install -g firebase-tools
  • We need to log in to Firebase to access and manage our projects. From the project root, from the terminal enter the command:
firebase login
  • Now, we can get the FlutterFire CLI using the command below:
dart pub global activate flutterfire_cli

With FlutterFire active, we will link our Flutter project in Android Studio to the Firebase Console project we created a few steps back.

  • Run this command:
flutterfire configure

A series of prompts show up, requiring you to select:

  • Your Firebase console project (from a list of all your Firebase projects.)

  • The platforms to support, e.g. Android, IOS, web.

  • Other services to activate, e.g., storage, authentication, real-time database, etc. We only need the authentication feature for now.

After successfully completing the configuration steps, Firebase generates a configuration file firebase_options.dart and adds it to the Flutter project.

#3. Integrating Firebase Authentication

Firebase Authentication provides a secure way to handle user authentication in your Flutter app. With our app already linked to Firebase, we can integrate Firebase services like user authentication.

Follow the steps below:

  • In your console, go to Authentication -> Sign-in method.

  • Enable the Google authentication provider from the list of providers.

Fig.4: Selecting a provider

Note: To use Google Sign-in in Android apps, we need to generate a SHA-1 certificate, this enables the Google Play services to create an OAuth2 client and API key for our app.

  • Open the Android folder in your Flutter project.

  • Open the gradle.build file in the terminal and run the command below:

./gradlew signingReport
  • Copy the generated certificate and head over to your Firebase console project.

  • Go to Project settings -> add fingerprints, and paste the SHA-1 certificate.

#4. Implementing an OAuth2 Client

Now it's time to implement the OAuth sign-in functionality in our Flutter app using Firebase Authentication.

  • Add the necessary Firebase Core and Authentication dependencies to your Flutter project's pubspec.yaml file. From the project's root, run:
dart pub add firebase_core
dart pub add firebase_auth
flutter pub get
  • Add the Google OAuth provider package google_sign_in to use the callbacks that will interact with the user authentication APIs.
dart pub add google_sign_in

Implementing Google sign-in in Flutter code

Finally, we need to implement the sign-in flow using Firebase Authentication methods and the Google OAuth provider package. This typically involves invoking the provider's sign-in method and handling the authentication response and token exchange.

  • Set up the app by initializing Firebase in the main.dart file.
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My Flutter App',
      // ...
    );
  }
}

To implement Google sign-in, we could use a variety of methods, but the approach I use is to implement the authentication logic in state management classes like Providers.

  • Create an AuthProvider class with the code below:
import 'package:flutter/foundation.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:firebase_auth/firebase_auth.dart';

enum Status {
  uninitialized,
  authenticated,
  authenticating,
  authenticateError,
  authenticateCanceled,
}

class AuthProvider with ChangeNotifier {
  final GoogleSignIn googleSignIn;
  final FirebaseAuth firebaseAuth;

  Status _status = Status.uninitialized;

  Status get status => _status;

  AuthProvider({
    required this.googleSignIn,
    required this.firebaseAuth,
  });

  Future<bool> handleGoogleSignIn() async {
    try {
      // Step 1: Set the status to "authenticating" and notify listeners.
      _status = Status.authenticating;
      notifyListeners();

      // Step 2: Perform Google Sign-In.
      final googleUser = await googleSignIn.signIn();
      if (googleUser == null) {
        _status = Status.authenticateCanceled;
        notifyListeners();
        return false;
      }

      // Step 3: Sign in to Firebase with Google credentials.
      final googleAuth = await googleUser.authentication;
      final credential = GoogleAuthProvider.credential(
        accessToken: googleAuth.accessToken,
        idToken: googleAuth.idToken,
      );

      final userCredential = await firebaseAuth.signInWithCredential(credential);

      if (userCredential.user != null) {
        // Sign-In Successful
        _status = Status.authenticated;
        notifyListeners();
        return true;
      } else {
        // Sign-In Error
        _status = Status.authenticateError;
        notifyListeners();
        return false;
      }
    } on FirebaseAuthException catch (e) {
      // Handle FirebaseAuth exceptions
      _status = Status.authenticateError;
      notifyListeners();
      return false;
    } catch (e) {
      // Handle other exceptions
      _status = Status.authenticateError;
      notifyListeners();
      return false;
    }
  }

  // Rest of the code (including sign-out)...

Future<void> googleSignOut() async {
    _status = Status.uninitialized;
    await firebaseAuth.signOut();
    await googleSignIn.signOut();

    notifyListeners();
  }

}

Here are the crucial steps in the code:

  1. Step 1: This step prepares the UI to indicate that the authentication process is in progress.

  2. Step 2: This involves the user selecting their Google account and providing consent for your app to access their account information.

  3. Step 3: The Google Sign-In credentials are exchanged for Firebase authentication, allowing the user to access Firebase features.

We can then use this code in LoginScreen when the user clicks on a sign-in button, I have kept the code as simple as possible:


class LoginScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final authProvider = Provider.of<AuthProvider>(context);

    return Scaffold(
      appBar: AppBar(
        title: Text('Login Screen'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () async {
                bool isSuccess = await authProvider.handleSignIn();

                if (isSuccess) {
                  Navigator.pushReplacement(
                    context,
                    MaterialPageRoute(builder: (context) => const Homepage()),
                  );
                }
              },
            ),
          ],
        ),
      ),
    );
  }
}

#5. Managing User Profiles and Data

Once users are authenticated, we can leverage Firebase to manage user profiles and store additional user data. We can:

  • Retrieve user profile information (e.g., name, email, profile picture) from the OAuth providers.

  • Store and manage user data using Firebase Firestore or Realtime Database. This can include custom user data, preferences, or additional user-related information.

Conclusion

This comprehensive guide explored the step-by-step process of implementing OAuth in Flutter using Firebase Authentication. By leveraging Firebase's features and integrating Google OAuth provider, we streamlined the user authentication process in our Flutter app, enabling users to sign in with their Google account. In upcoming articles, I will write about other Oauth providers like Facebook and Twitter. Stay tuned!