Set up Firebase Google sign-in in a Flutter web app

Updated Oct 27, 2026 · Pewterkit Guides

On Flutter web, sign users in with FirebaseAuth.instance.signInWithPopup(GoogleAuthProvider()): the Firebase SDK runs the Google flow itself on web, so you don't need the google_sign_in plugin there. Enable the Google provider, add every domain you serve from to Firebase's authorized domains, and keep google_sign_in for your Android and iOS builds only.

What you need (as of Oct 2026)

  • A Flutter project with web enabled and a Firebase project.
  • Package versions current when this page was checked: firebase_auth 7.0.1, google_sign_in 7.2.0 (its web implementation google_sign_in_web is 1.1.3). firebase_auth supports Android, iOS, macOS, web and Windows.

Step 1: Add Firebase to the Flutter app

Run flutterfire configure and select Web among the platforms. It creates lib/firebase_options.dart. Initialize Firebase before runApp:

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'firebase_options.dart';

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

Add the packages:

flutter pub add firebase_core firebase_auth google_sign_in

Step 2: Turn on the Google provider

In the Firebase console, open Security > Authentication > Sign-in method (older guides say Build > Authentication), enable Google, and save. Console labels as of Oct 2026.

Step 3: Write one sign-in function for web and mobile

FlutterFire documents two different routes: on web, the Firebase SDK handles the flow with a GoogleAuthProvider; on Android and iOS, a third-party library (google_sign_in) gets an ID token that you pass to signInWithCredential. One function can cover both:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:google_sign_in/google_sign_in.dart';

Future<UserCredential> signInWithGoogle() async {
  if (kIsWeb) {
    final provider = GoogleAuthProvider();
    // Optional: provider.addScope('https://www.googleapis.com/auth/contacts.readonly');
    return FirebaseAuth.instance.signInWithPopup(provider);
  }

  // Android / iOS: call GoogleSignIn.instance.initialize() once at startup first.
  final GoogleSignInAccount googleUser =
      await GoogleSignIn.instance.authenticate();
  final credential = GoogleAuthProvider.credential(
    idToken: googleUser.authentication.idToken,
  );
  return FirebaseAuth.instance.signInWithCredential(credential);
}

Call it straight from the button's onPressed, with no other await first. Browsers only open a popup in direct response to user input, and that window of permission expires.

Listen for the signed-in user anywhere in the app:

FirebaseAuth.instance.authStateChanges().listen((User? user) {
  // user is null when signed out
});
signInWithPopup signInWithRedirect
What the user sees A Google window over your app The whole tab goes to Google and back
Extra code None Call FirebaseAuth.instance.getRedirectResult() on startup (web only)
Main risk Popup blockers; Firebase says it's less smooth on mobile Fails with "missing initial state" in Chrome M115+, Firefox 109+ and Safari 16.1+ unless the auth handler is on your app's domain
Good default when You haven't moved the auth handler to your domain You've done Step 5 below

If you already hit the redirect error, see Missing initial state in Flutter. For a wider comparison, see Popup or redirect?.

What changed in google_sign_in 7.x on web

If you followed an older tutorial that used google_sign_in on web, expect it to break:

  • authenticate() is not supported on web. supportsAuthenticate() returns false there and calling authenticate() throws.
  • Google Identity Services only allows sign-in through its own UI, so the web plugin gives you a button from renderButton() (in web_only.dart) and reports sign-in through authenticationEvents.
  • Google Identity Services does not renew sessions. The ID token expires after 3600 seconds, and the plugin's docs point apps that need long sessions to a provider such as Firebase Auth.

That's why the function above uses Firebase's own popup on web. If you still use google_sign_in on web (for example, to call Google APIs), you need:

  1. A meta tag in the <head> of web/index.html:
<meta name="google-signin-client_id" content="YOUR_WEB_CLIENT_ID.apps.googleusercontent.com">
  1. Your origins under Authorized JavaScript origins for that OAuth client, including http://localhost and http://localhost:7357 for local work.
  2. A fixed local port that matches:
flutter run -d chrome --web-hostname localhost --web-port 7357

Step 4: Add your domains to authorized domains

Every domain that runs your sign-in code needs to be on Firebase's authorized domains list. Open Security > Authentication > Settings > Authorized domains (older path: Build > Authentication > Settings) and click Add domain for:

  • localhost, if you test locally. Firebase projects created after April 28, 2025 no longer include localhost by default.
  • Every domain that serves your Flutter web build in production.

If sign-in throws auth/unauthorized-domain, a domain is missing from this list; see Firebase authorized domains.

Step 5 (optional): Show your own domain on the Google screen

By default, Google's consent screen says "Continue to: <project>.firebaseapp.com" because that's your authDomain. Firebase documents how to show your own domain instead, using Firebase Hosting:

  1. Connect a custom domain to Firebase Hosting (Hosting > Add custom domain, then the TXT and A records the console shows; SSL can take up to 24 hours).
  2. Add that domain to Authorized domains (Step 4).
  3. Add https://app.example.com/__/auth/handler to the OAuth web client's Authorized redirect URIs in Google Cloud console.
  4. Set authDomain for the web build. firebase_options.dart is generated by flutterfire configure, so override it in main.dart rather than editing the generated file:
final base = DefaultFirebaseOptions.currentPlatform;
await Firebase.initializeApp(
  options: kIsWeb ? base.copyWith(authDomain: 'app.example.com') : base,
);
  1. Build and deploy. With a plain Firebase Hosting setup, point public in firebase.json at the Flutter output folder:
{
  "hosting": {
    "public": "build/web"
  }
}
flutter build web
firebase deploy

authDomain is only used for OAuth redirects on web, so the kIsWeb check leaves mobile builds alone. If your Flutter web app is hosted somewhere other than Firebase Hosting, the handler has to be proxied or self-hosted instead; the steps per host are in How to change your Firebase authDomain.

How to confirm it worked

  • Click the button: a Google window opens, closes, and authStateChanges() emits a non-null User.
  • The user appears in the Firebase console under Authentication > Users.
  • After Step 5, the Google screen names your domain, and DevTools > Network shows /__/auth/handler loading from your domain.
  • Test the deployed URL, not only localhost, since each domain needs its own authorized-domain entry.

FAQ

Do I need the google-signin-client_id meta tag for Firebase sign-in on web?

Not if you use FirebaseAuth.instance.signInWithPopup or signInWithRedirect. The meta tag is part of the google_sign_in_web plugin's setup, which you only need if you use that plugin on web.

Should I use signInWithPopup or signInWithRedirect on Flutter web?

Start with the popup. The redirect needs the auth handler on your own domain in current Chrome, Firefox and Safari versions, per Firebase's redirect guide.

Why does sign-in work on localhost but not after I deploy?

Each domain must be listed under Authorized domains in the Firebase console. Add your production domain there; it's a project setting, so no code change is needed.

Can the same Dart function run on Android?

Yes, the kIsWeb branch sends mobile builds through google_sign_in and signInWithCredential. For Android, Firebase also needs your app's SHA-1 fingerprint.

Sources

  1. Federated identity & social sign-in, Flutter (Firebase)
  2. Get started with Firebase Authentication on Flutter (Firebase)
  3. Add Firebase to your Flutter app (Firebase)
  4. Authenticate Using Google with JavaScript: custom domain on the consent screen (Firebase)
  5. Best practices for using signInWithRedirect on browsers that block third-party storage access (Firebase)
  6. Authenticate with Firebase using email link: authorized domains and localhost (Firebase)
  7. Connect a custom domain (Firebase Hosting)
  8. Configure Hosting behavior: the public attribute (Firebase Hosting)
  9. firebase_auth package (pub.dev)
  10. FirebaseAuth.signInWithPopup (pub.dev)
  11. FirebaseAuth.getRedirectResult (pub.dev)
  12. FirebaseOptions.authDomain (pub.dev)
  13. FirebaseOptions.copyWith (pub.dev)
  14. google_sign_in package (pub.dev)
  15. google_sign_in_web package (pub.dev)
  16. MDN: Window.open() and popup blockers
  17. Build and release a web app (Flutter docs)

How this page was made: drafted with AI from the sources listed, reviewed by Pewterkit. Docs checked Oct 27, 2026. Spotted something out of date? Tell us.

Related guides