image

04 Apr 2026

9K

35K

Flutter & Firebase Auth: Implementing SSO with Multiple OAuth2 Providers

Modern applications frequently require users to authenticate seamlessly using their existing social media or enterprise accounts. Single Sign-On (SSO) simplifies this process, enhancing user experience and improving security. When building cross-platform applications with Flutter, Firebase Authentication provides a robust and flexible backend solution for implementing SSO with various OAuth2 providers.

This article will guide you through setting up a Flutter application to authenticate users using multiple OAuth2 providers like Google, Facebook, and Apple, all powered by Firebase Auth. We'll cover the necessary configurations, package installations, and code implementations to achieve a unified authentication flow.

Prerequisites

  • A Flutter development environment set up.
  • A Firebase project configured.
  • Familiarity with basic Flutter development.
  • Basic understanding of Firebase Authentication.

1. Firebase Project Setup

First, you need to enable the desired authentication methods in your Firebase project.

1.1. Create/Configure Firebase Project

If you haven't already, create a new Firebase project or use an existing one. Register your Flutter application with Firebase by adding your Android package name (applicationId) and SHA-1/SHA-256 certificates (for Google Sign-In on Android) and your iOS bundle ID.

  • Download google-services.json for Android and place it in android/app/.
  • Download GoogleService-Info.plist for iOS and place it in ios/Runner/.

1.2. Enable Authentication Providers

Navigate to the Firebase Console -> Authentication -> Sign-in method tab. Enable the following providers:

  • Google:
    • Enable it. Firebase typically auto-configures the web client ID.
    • Ensure your Flutter app's SHA-1 fingerprint is added in Project Settings -> Android apps.
  • Facebook:
    • You'll need an app created in the Facebook Developer Console.
    • Provide the Facebook App ID and App Secret.
    • Add the OAuth redirect URI from Firebase to your Facebook app's settings (Products -> Facebook Login -> Settings -> Valid OAuth Redirect URIs).
  • Apple:
    • Enable it.
    • You'll need to register your bundle ID with Apple, enable Sign In with Apple capability, and potentially configure a Services ID (for web-based flow, not strictly necessary for native iOS).

2. Flutter Project Setup

Next, we need to add the necessary dependencies to our Flutter project.

2.1. Add Dependencies

Open your pubspec.yaml file and add the following dependencies:


dependencies:
  flutter:
    sdk: flutter
  firebase_core: ^2.24.2
  firebase_auth: ^4.15.2
  google_sign_in: ^6.1.6 # For Google Sign-In
  flutter_facebook_auth: ^6.1.0 # For Facebook Sign-In
  sign_in_with_apple: ^6.1.0 # For Apple Sign-In

Run flutter pub get to install these packages.

2.2. Initialize Firebase

Ensure Firebase is initialized correctly in your main.dart file.


import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart'; // Generated by FlutterFire CLI

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Firebase SSO',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AuthScreen(),
    );
  }
}

The firebase_options.dart file is generated by the FlutterFire CLI. If you haven't done so, install the CLI (dart pub global activate flutterfire_cli) and run flutterfire configure in your project root.

2.3. Platform-Specific Configurations

Android

  • No additional code configuration for Facebook beyond google-services.json (already covered).

iOS

  • Facebook:

    Add the following to your ios/Runner/Info.plist file:

    
    <key>CFBundleURLTypes</key>
    <array>
    	<dict>
    		<key>CFBundleURLSchemes</key>
    		<array>
    			<string>fb[YOUR_FACEBOOK_APP_ID]</string>
    		</array>
    	</dict>
    </array>
    <key>FacebookAppID</key>
    <string>[YOUR_FACEBOOK_APP_ID]</string>
    <key>FacebookDisplayName</key>
    <string>[YOUR_APP_DISPLAY_NAME]</string>
    <key>LSApplicationQueriesSchemes</key>
    <array>
    	<string>fbapi</string>
    	<string>fb-messenger-share-api</string>
    	<string>fbauth2</string>
    	<string>fbshareextension</string>
    </array>
    

    Replace [YOUR_FACEBOOK_APP_ID] and [YOUR_APP_DISPLAY_NAME].

  • Apple Sign-In:

    In Xcode, navigate to your project settings, select your target, and go to the "Signing & Capabilities" tab. Click "+ Capability" and add "Sign In with Apple".

3. Implementing Authentication Logic

Now, let's write the Flutter code to handle sign-in with each provider.

3.1. Google Sign-In


import 'package:firebase_auth/firebase_auth.dart';
import 'package:google_sign_in/google_sign_in.dart';

Future<UserCredential?> signInWithGoogle() async {
  try {
    // Trigger the authentication flow
    final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();

    // Obtain the auth details from the request
    final GoogleSignInAuthentication? googleAuth = await googleUser?.authentication;

    if (googleAuth?.accessToken != null && googleAuth?.idToken != null) {
      // Create a new credential
      final credential = GoogleAuthProvider.credential(
        accessToken: googleAuth!.accessToken,
        idToken: googleAuth.idToken,
      );

      // Sign in to Firebase with the credential
      return await FirebaseAuth.instance.signInWithCredential(credential);
    }
  } on FirebaseAuthException catch (e) {
    print("Firebase Auth Error for Google: ${e.message}");
  } catch (e) {
    print("Google Sign-In Error: $e");
  }
  return null;
}

3.2. Facebook Sign-In


import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter_facebook_auth/flutter_facebook_auth.dart';

Future<UserCredential?> signInWithFacebook() async {
  try {
    final LoginResult result = await FlutterFacebookAuth.instance.login();

    if (result.status == LoginStatus.success) {
      // Get the access token
      final AccessToken? accessToken = result.accessToken;

      if (accessToken != null) {
        // Create a Facebook credential
        final credential = FacebookAuthProvider.credential(accessToken.token);

        // Sign in to Firebase with the credential
        return await FirebaseAuth.instance.signInWithCredential(credential);
      }
    } else if (result.status == LoginStatus.cancelled) {
      print('Facebook login cancelled.');
    } else {
      print('Facebook login failed: ${result.message}');
    }
  } on FirebaseAuthException catch (e) {
    print("Firebase Auth Error for Facebook: ${e.message}");
  } catch (e) {
    print("Facebook Sign-In Error: $e");
  }
  return null;
}

3.3. Apple Sign-In


import 'package:firebase_auth/firebase_auth.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';

Future<UserCredential?> signInWithApple() async {
  try {
    final AuthorizationCredentialAppleID appleCredential = await SignInWithApple.getAppleIDCredential(
      scopes: [
        AppleIDButtonType.signIn,
        AppleIDButtonType.signUp,
        AppleIDButtonType.continueWithApple,
      ],
      webAuthenticationOptions: ( // Optional, for web-based flow on non-Apple devices
        // For example, if you want to support Apple Sign In on Android/Web
        // you'd need to configure a Firebase Apple OAuth provider
        // and specify clientId and redirectUri here.
        // For native iOS, this can often be null.
        // Check Firebase console for your Apple provider's settings.
        // clientId: 'YOUR_FIREBASE_APPLE_OAUTH_CLIENT_ID',
        // redirectUri: Uri.parse('YOUR_FIREBASE_APPLE_REDIRECT_URI'),
      ),
    );

    if (appleCredential.identityToken != null) {
      // Create a Firebase credential from the Apple credential
      final credential = AppleAuthProvider.credential(
        idToken: appleCredential.identityToken,
        accessToken: appleCredential.authorizationCode, // The authorizationCode is often used as access token by Firebase
      );

      // Sign in to Firebase with the credential
      return await FirebaseAuth.instance.signInWithCredential(credential);
    }
  } on FirebaseAuthException catch (e) {
    print("Firebase Auth Error for Apple: ${e.message}");
  } on SignInWithAppleAuthorizationException catch (e) {
    print("Apple Sign-In Error: ${e.code} - ${e.message}");
    // Handle specific Apple sign-in errors like cancellation
  } catch (e) {
    print("Generic Apple Sign-In Error: $e");
  }
  return null;
}

3.4. Generic OAuth2 Providers (e.g., GitHub, Twitter, Microsoft)

For providers not natively supported by client-side SDKs, Firebase offers a generic OAuthProvider. This typically involves opening a web browser for the authentication flow and redirecting back to your app.


import 'package:firebase_auth/firebase_auth.dart';

Future<UserCredential?> signInWithGenericOAuth(String providerId) async {
  try {
    // For example, 'github.com', 'twitter.com', 'microsoft.com'
    final OAuthProvider oAuthProvider = OAuthProvider(providerId);
    oAuthProvider.addScope('user:email'); // Example scope for GitHub

    // For web and mobile flows that don't use SDKs
    // The signInWithPopup or signInWithRedirect method will handle the web view.
    // On mobile, this will open the default browser.
    return await FirebaseAuth.instance.signInWithProvider(oAuthProvider);
  } on FirebaseAuthException catch (e) {
    print("Firebase Auth Error for $providerId: ${e.message}");
  } catch (e) {
    print("Generic OAuth Sign-In Error for $providerId: $e");
  }
  return null;
}

4. Handling SSO and Account Linking

Firebase Auth automatically handles account linking when users sign in with different providers but use the same verified email address. For example, if a user signs in with Google using [email protected], and then later signs in with Facebook also using [email protected], Firebase links these accounts, and the User object will reflect both provider IDs.

If a user attempts to sign in with a new provider, but an existing Firebase account already exists with a *different* email address, Firebase might prompt you to link the accounts explicitly. You can achieve this using currentUser.linkWithCredential().


Future<UserCredential?> linkAccounts(AuthCredential credential) async {
  try {
    final User? user = FirebaseAuth.instance.currentUser;
    if (user != null) {
      return await user.linkWithCredential(credential);
    }
  } on FirebaseAuthException catch (e) {
    if (e.code == 'credential-already-in-use') {
      print('This credential is already associated with another account.');
      // Handle merging accounts or showing an error
    } else {
      print('Error linking account: ${e.message}');
    }
  } catch (e) {
    print('Unknown error linking account: $e');
  }
  return null;
}

5. User Management and UI

You can observe authentication state changes to update your UI accordingly and manage user sessions.


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

class AuthScreen extends StatefulWidget {
  const AuthScreen({super.key});

  @override
  State<AuthScreen> createState() => _AuthScreenState();
}

class _AuthScreenState extends State<AuthScreen> {
  User? _currentUser;

  @override
  void initState() {
    super.initState();
    FirebaseAuth.instance.authStateChanges().listen((User? user) {
      setState(() {
        _currentUser = user;
      });
    });
  }

  Future<void> _signOut() async {
    await FirebaseAuth.instance.signOut();
    await GoogleSignIn().signOut(); // Also sign out from Google
    await FlutterFacebookAuth.instance.logOut(); // Also sign out from Facebook
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Firebase SSO')),
      body: Center(
        child: _currentUser == null
            ? Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  ElevatedButton(
                    onPressed: () async {
                      await signInWithGoogle();
                    },
                    child: const Text('Sign in with Google'),
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      await signInWithFacebook();
                    },
                    child: const Text('Sign in with Facebook'),
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      await signInWithApple(); // Only visible on iOS
                    },
                    child: const Text('Sign in with Apple'),
                  ),
                  ElevatedButton(
                    onPressed: () async {
                      await signInWithGenericOAuth('github.com');
                    },
                    child: const Text('Sign in with GitHub'),
                  ),
                ],
              )
            : Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text('Welcome, ${_currentUser!.displayName ?? _currentUser!.email}!'),
                  Text('Provider(s): ${_currentUser!.providerData.map((e) => e.providerId).join(', ')}'),
                  ElevatedButton(
                    onPressed: _signOut,
                    child: const Text('Sign Out'),
                  ),
                ],
              ),
      ),
    );
  }
}

Conclusion

Implementing SSO with multiple OAuth2 providers in Flutter using Firebase Authentication significantly enhances user experience by offering flexible and familiar sign-in options. By following the steps outlined in this guide – from Firebase console configurations to platform-specific setups and Flutter code – you can create a robust authentication system that integrates seamlessly with major identity providers. Firebase's automatic account linking further simplifies user management, making it an excellent choice for modern cross-platform applications.

Related Articles

May 14, 2026

Building a Multi-Event Countdown Timer Widget with Reminders, Notifications, Repeat, and Custom Labels in Flutter

Building a Multi-Event Countdown Timer Widget with Reminders, Notifications, Repeat, and Custom Labels in Flutter Countdown timers are essential in many applic

May 11, 2026

Unleashing Dynamic UIs: Flutter's Animation Prowess

Unleashing Dynamic UIs: Flutter's Animation Prowess for Slide & Scale Effects Flutter's declarative UI framework, combined with its powerful animation capabilit

May 11, 2026

Building a Product Detail Page Widget in Flutter with Related Items, Review Carousel, Promo Badges, and Quick Buy

Building a Product Detail Page Widget in Flutter with Related Items, Review Carousel, Promo Badges, and Quick Buy A well-designed Product Detail Page (PDP) is