The Flutter Kit logoThe Flutter Kit
Guide

How to Add Authentication to a Flutter App: Firebase Auth + Apple & Google, the Kit Way

Wire Firebase Auth with Sign in with Apple, Google, email, and anonymous sign-in into a Flutter app from zero using BLoC and get_it. Do it by hand below, or drop into The Flutter Kit where it already works on iOS, Android, and Web.

Last updated: 2026-06-10 8 min read By Ahmed Gagan, Flutter Engineer
Quick Answer

To add authentication to a Flutter app the kit way, you wire Firebase Auth with Sign in with Apple, Google, email/password, and anonymous sign-in behind a single AuthRepository, then expose state through an AuthCubit so go_router can react. The Flutter Kit ($69 one-time, unlimited projects, lifetime updates) ships exactly this — all four providers pre-wired across iOS, Android, and Web — so you skip the OAuth plumbing and Apple's nonce/credential dance entirely.

Providers pre-wired
Email/password, Google, Apple, anonymous
Architecture
AuthRepository + AuthCubit, injected via get_it
Platforms from one codebase
iOS, Android, and Web

Why an AuthRepository beats raw FirebaseAuth calls

The fastest-looking way to add authentication to a Flutter app is to call FirebaseAuth.instance directly inside your login widget. It works in a demo and rots in production. The moment you add a second provider, a password reset, account linking, or want to swap Firebase for Supabase, those scattered calls become a refactor you dread. The kit way is one AuthRepository that owns every provider and exposes a single authState stream, plus an AuthCubit that translates that stream into states your UI and router consume. Because the repository is the only thing that imports firebase_auth, your screens stay backend-agnostic — and since you own the source, replacing the repository internals with Supabase auth is a contained change, not a rewrite.

  • UI never imports a provider SDK — only the repository does
  • Account linking (anonymous to Google/Apple) lives in one place
  • Swapping Firebase for Supabase touches one file, not fifty

When you should skip the kit and do it yourself

This page is honest: if you only need email/password and will never ship to the App Store, hand-rolling Firebase Auth is a couple of evenings and you should just do it — a starter kit is overkill. The same goes if your team already has a battle-tested auth package or a BFF that issues your own JWTs; bolting Firebase on top adds a dependency you don't need. The Flutter Kit earns its $69 the moment Sign in with Apple enters the picture, because Apple's nonce hashing, first-sign-in name capture, Android web-fallback, and the iOS entitlement plus reversed-client-ID Google URL scheme are exactly the steps people lose a day to. If that's your situation, the kit ships all four providers wired through the AuthRepository/AuthCubit pattern, tested across iOS, Android, and Web, with the platform setup documented step by step.

Add Firebase Auth + Apple & Google to Flutter, step by step

This is the from-zero path. Each step is what The Flutter Kit already does for you out of the box — so do it by hand, or skip the plumbing and own a working AuthRepository on day one.

  1. 1

    Create the Firebase project and connect FlutterFire

    Spin up a Firebase project, enable Email/Password, Google, Apple, and Anonymous providers in the Authentication console, then run flutterfire configure to generate firebase_options.dart for iOS, Android, and Web. The kit ships this config wiring and just asks for your project keys.

    dart pub global activate flutterfire_cli
    flutterfire configure
    flutter pub add firebase_core firebase_auth google_sign_in sign_in_with_apple
  2. 2

    Initialize Firebase before runApp

    Call Firebase.initializeApp with your generated options inside an async main(). Skip this and every auth call throws a no-app error. In the kit this lives in a bootstrap() function alongside get_it registration and crash reporting.

  3. 3

    Wrap providers in a single AuthRepository

    Instead of scattering FirebaseAuth.instance calls across widgets, funnel email, Google, Apple, and anonymous flows through one repository so your UI never touches a provider SDK directly. This is the architectural seam that makes Supabase swappable later.

    class AuthRepository {
      AuthRepository(this._auth);
      final FirebaseAuth _auth;
    
      Stream<User?> get authState => _auth.authStateChanges();
    
      Future<UserCredential> signInWithGoogle() async {
        final g = await GoogleSignIn().signIn();
        final t = await g!.authentication;
        final cred = GoogleAuthProvider.credential(
          idToken: t.idToken, accessToken: t.accessToken);
        return _auth.signInWithCredential(cred);
      }
    }
  4. 4

    Handle Sign in with Apple's nonce correctly

    Apple requires a SHA-256 hashed nonce and returns the user's name only on first sign-in, so you must persist it then. Get this wrong and Apple rejects the credential or you lose the display name forever. The kit hashes the nonce, captures the name on first grant, and handles the Android-via-web fallback.

    final raw = generateNonce();
    final apple = await SignInWithApple.getAppleIDCredential(
      scopes: [AppleIDAuthorizationScopes.email, AppleIDAuthorizationScopes.fullName],
      nonce: sha256.convert(utf8.encode(raw)).toString(),
    );
    final oauth = OAuthProvider('apple.com').credential(
      idToken: apple.identityToken, rawNonce: raw);
  5. 5

    Expose auth state through an AuthCubit

    Listen to authStateChanges() in a Cubit and emit Authenticated, Unauthenticated, or Loading. Register both the repository and Cubit in get_it so any screen resolves them via dependency injection rather than constructing Firebase by hand.

  6. 6

    Gate routes with go_router redirect

    Use the Cubit's stream as a refreshListenable and a redirect callback to bounce unauthenticated users to the login screen and signed-in users away from it. The kit wires this redirect plus deep-link-safe return paths already.

  7. 7

    Configure native sign-in entitlements

    On iOS add the Sign in with Apple capability and a reversed-client-ID URL scheme for Google; on Android add the SHA-1/SHA-256 fingerprints in Firebase. These platform steps are the most common reason a build compiles but sign-in silently fails — the kit documents each in its setup checklist.

    keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android

Frequently Asked Questions

Do I need Sign in with Apple if I already support Google sign-in in my Flutter app?
Yes, if you ship to the iOS App Store. Apple's review guidelines require Sign in with Apple as an option whenever you offer a third-party social login like Google. The Flutter Kit wires Apple alongside Google so you pass review without scrambling, including the nonce hashing Apple demands.
Why does Sign in with Apple lose the user's name on the second login?
Apple returns the full name and email only on the very first authorization for an app; subsequent sign-ins return null for those fields. You must persist the name to Firestore on first grant. The kit captures and stores it on first sign-in so your profile screen always has a display name.
Can I use this Firebase Auth setup on Flutter Web too?
Yes. The AuthRepository pattern works across iOS, Android, and Web from one Dart codebase. Google sign-in uses a popup flow on Web and Apple falls back to its web-based OAuth on Android and Web — The Flutter Kit handles both fallbacks so the same login screen works on every target.
How does authentication state stay in sync with go_router?
You feed the AuthCubit's stream into go_router as a refreshListenable and use a redirect callback. When the user signs in or out, the router re-evaluates and bounces them to the right screen. The kit ships this redirect plus deep-link-safe return paths, so a signed-out user hitting a protected deep link lands back there after logging in.
Is the auth in The Flutter Kit locked to Firebase, or can I switch to Supabase?
It defaults to Firebase Auth, but because every provider funnels through a single AuthRepository and you own the full source, swapping in Supabase auth is a contained change to one file rather than a rewrite. The UI and router never import the backend SDK directly.
Does adding all these providers slow down the login screen?
No. Provider SDKs initialize lazily and the AuthCubit only listens to a single authStateChanges() stream, so the login screen renders instantly with Impeller. Anonymous sign-in lets users into the app immediately and you upgrade them to a full account later via account linking.

Keep exploring

Skip the OAuth plumbing

The Flutter Kit ships Firebase Auth with Sign in with Apple, Google, email, and anonymous sign-in already wired through AuthRepository and AuthCubit, tested on iOS, Android, and Web. $69 one-time, unlimited projects, lifetime updates, full source ownership.

Get The Flutter Kit — $69

One-time purchase · Lifetime updates · Unlimited projects