Set up Firebase Google sign-in in a Flutter web app
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_auth7.0.1,google_sign_in7.2.0 (its web implementationgoogle_sign_in_webis 1.1.3).firebase_authsupports 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
});
Popup or redirect on Flutter web?
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 callingauthenticate()throws.- Google Identity Services only allows sign-in through its own UI, so the web plugin gives you a button from
renderButton()(inweb_only.dart) and reports sign-in throughauthenticationEvents. - 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:
- A meta tag in the
<head>ofweb/index.html:
<meta name="google-signin-client_id" content="YOUR_WEB_CLIENT_ID.apps.googleusercontent.com">
- Your origins under Authorized JavaScript origins for that OAuth client, including
http://localhostandhttp://localhost:7357for local work. - 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 includelocalhostby 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:
- 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).
- Add that domain to Authorized domains (Step 4).
- Add
https://app.example.com/__/auth/handlerto the OAuth web client's Authorized redirect URIs in Google Cloud console. - Set
authDomainfor the web build.firebase_options.dartis generated byflutterfire configure, so override it inmain.dartrather than editing the generated file:
final base = DefaultFirebaseOptions.currentPlatform;
await Firebase.initializeApp(
options: kIsWeb ? base.copyWith(authDomain: 'app.example.com') : base,
);
- Build and deploy. With a plain Firebase Hosting setup, point
publicinfirebase.jsonat 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-nullUser. - The user appears in the Firebase console under Authentication > Users.
- After Step 5, the Google screen names your domain, and DevTools > Network shows
/__/auth/handlerloading from your domain. - Test the deployed URL, not only
localhost, since each domain needs its own authorized-domain entry.
Related problems
auth/unauthorized-domainon localhost or after deploying: Firebase authorized domains- Redirect sign-in loops back with an error: Missing initial state in Flutter
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
- Federated identity & social sign-in, Flutter (Firebase)
- Get started with Firebase Authentication on Flutter (Firebase)
- Add Firebase to your Flutter app (Firebase)
- Authenticate Using Google with JavaScript: custom domain on the consent screen (Firebase)
- Best practices for using signInWithRedirect on browsers that block third-party storage access (Firebase)
- Authenticate with Firebase using email link: authorized domains and localhost (Firebase)
- Connect a custom domain (Firebase Hosting)
- Configure Hosting behavior: the public attribute (Firebase Hosting)
- firebase_auth package (pub.dev)
- FirebaseAuth.signInWithPopup (pub.dev)
- FirebaseAuth.getRedirectResult (pub.dev)
- FirebaseOptions.authDomain (pub.dev)
- FirebaseOptions.copyWith (pub.dev)
- google_sign_in package (pub.dev)
- google_sign_in_web package (pub.dev)
- MDN: Window.open() and popup blockers
- 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 26 Oct 2026. Spotted something out of date? Tell us.