Fix "missing initial state" in Flutter Firebase Google sign-in

Updated Oct 27, 2026 · Pewterkit Guides

In a Flutter app, "Unable to process request due to missing initial state" means Firebase's sign-in handler page could not read the state it saved in sessionStorage before sending the user to Google. On Flutter web, switch to signInWithPopup or serve the auth handler from your app's own domain; on Android, use the native google_sign_in flow with signInWithCredential and skip the browser hop.

Why it happens in a Flutter app

The full error text reads: "Unable to process request due to missing initial state. This may happen if browser sessionStorage is inaccessible or accidentally cleared." It names "using signInWithRedirect in a storage-partitioned browser environment" as one of the triggers.

Firebase's redirect flow runs through a helper page at https://<authDomain>/__/auth/handler and a cross-origin iframe. By default authDomain is <project>.firebaseapp.com. If your Flutter web build is served from any other site, that helper is a third party, and browsers that partition or block third-party storage keep it from reading its own state. Firebase says a fix is required on Chrome M115+ (from June 24, 2024), Firefox 109+ and Safari 16.1+. A comment on the Firebase JS SDK issue tracker sums up the most common cause: the auth helper code and the app are "NOT on the same origin."

For the plain-language meaning of the error, see What "missing initial state" means. This page covers the Flutter-specific causes and fixes.

Where your Flutter code runs Typical trigger Fix
Flutter web, signInWithRedirect, app not served from <project>.firebaseapp.com Storage partitioning between your domain and the auth helper domain Fix A or Fix B
Flutter web opened inside another app's in-app browser In-app browsers can turn popups into redirects, breaking the hand-off Fix B (a Firebase team comment advises against popup flows in in-app browsers)
Android app that loads your web app in a WebView Google blocks OAuth in embedded webviews (disallowed_useragent) Fix C
Android app using a browser-based provider flow An issue report of this exact error on Android Chrome and Samsung Internet Fix C

Step 1: Find which sign-in call your app makes

Run this from your project root:

grep -rn "signInWithRedirect\|signInWithProvider\|signInWithPopup\|getRedirectResult" lib/
  • signInWithRedirect on web: go to Fix A or Fix B.
  • signInWithProvider on Android, or a WebView that loads your sign-in page: go to Fix C.

Fix A (Flutter web): switch to signInWithPopup

This is Firebase's Option 2 and the smallest change. In FlutterFire, signInWithPopup is only available on web, so guard it with kIsWeb.

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

Future<UserCredential> signInWithGoogleWeb() {
  assert(kIsWeb, 'signInWithPopup is web-only');
  final provider = GoogleAuthProvider();
  return FirebaseAuth.instance.signInWithPopup(provider);
}

Then:

  1. Delete any getRedirectResult() call that only existed for the redirect flow.
  2. Call signInWithGoogleWeb() directly inside the button's onPressed, before any other await. Browsers only allow a popup in direct response to user input, and that permission expires, so loading data first can get the popup blocked. See auth/popup-blocked if that happens.

Firebase notes the trade-off: popups can be blocked by the device or platform, and the flow is less smooth on mobile.

Fix B (Flutter web): keep the redirect and serve the handler from your domain

Use this when you want the full-page redirect, or you want your own domain on the Google screen.

If your Flutter web build is on Firebase Hosting (a custom domain or a web.app subdomain), use Firebase's Option 1: set authDomain to the domain that serves the app. firebase_options.dart is generated by flutterfire configure, so a hand edit there can be lost the next time you run it. Override the value in main.dart instead. authDomain is only used for OAuth redirects on web platforms, so Android and iOS are unaffected.

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

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final base = DefaultFirebaseOptions.currentPlatform;
  await Firebase.initializeApp(
    options: kIsWeb ? base.copyWith(authDomain: 'app.example.com') : base,
  );
  runApp(const MyApp());
}

Then, as of Oct 2026:

  1. In Google Cloud console > APIs & Services > Credentials, open the OAuth 2.0 web client your Firebase project uses and add https://app.example.com/__/auth/handler to Authorized redirect URIs. The /__/auth/handler suffix is required.
  2. In the Firebase console, open Security > Authentication > Settings > Authorized domains (older guides say Build > Authentication > Settings) and make sure app.example.com is listed.
  3. Rebuild and redeploy so Hosting serves the current /__/firebase/init.json:
flutter build web
firebase deploy
  1. Read the redirect result once at startup, after Firebase.initializeApp:
if (kIsWeb) {
  final result = await FirebaseAuth.instance.getRedirectResult();
  if (result.user != null) {
    // Signed in via redirect.
  }
}

If your Flutter web build is on another host (Vercel, Netlify, Cloudflare, your own server), Firebase's Option 1 does not apply. Use Option 3 (reverse-proxy /__/auth/ to <project>.firebaseapp.com) or Option 4 (self-host the helper files). The host-by-host steps are in How to change your Firebase authDomain.

Fix C (Android and webviews): use the native Google sign-in

Do not run Google sign-in inside a WebView. Google has blocked its OAuth endpoint in embedded webviews since September 30, 2021, and affected apps get a disallowed_useragent error. For Android and iOS, FlutterFire's documented route is the google_sign_in plugin plus signInWithCredential, which never opens a browser and so never needs sessionStorage.

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

// Call once at startup on Android/iOS, before authenticate().
Future<void> initGoogleSignIn() => GoogleSignIn.instance.initialize();

Future<UserCredential> signInWithGoogleNative() async {
  final GoogleSignInAccount googleUser =
      await GoogleSignIn.instance.authenticate();
  final String? idToken = googleUser.authentication.idToken;
  final credential = GoogleAuthProvider.credential(idToken: idToken);
  return FirebaseAuth.instance.signInWithCredential(credential);
}

Notes (google_sign_in 7.x and firebase_auth 7.x, as of Oct 2026):

  • Android needs your app's SHA-1 fingerprint added in the Firebase project.
  • initialize() accepts clientId and serverClientId; check the platform README linked from the google_sign_in package page for whether your setup needs them.
  • If you replaced a browser-based signInWithProvider call on Android, remove it. An issue in the Firebase Android SDK tracker reports this exact error in Android Chrome and Samsung Internet for that kind of flow.

How to confirm it worked

  • Web, Fix A: a Google popup opens and closes, and FirebaseAuth.instance.currentUser is not null afterwards.
  • Web, Fix B: in browser DevTools > Network, the /__/auth/handler request goes to your own domain, not firebaseapp.com, and getRedirectResult() returns a user.
  • Android, Fix C: the native account picker appears, and the user shows up in the Firebase console under Authentication > Users.
  • Repeat the web test in a Firefox private window and in Safari, since Firebase lists both browsers as affected.

FAQ

Do I need google_sign_in for Flutter web?

No. FlutterFire's docs say that on web the Firebase SDK handles the Google flow itself through signInWithPopup or signInWithRedirect. In google_sign_in 7.x, authenticate() is not supported on web, and the web plugin only offers the button rendered by Google Identity Services.

Why does it fail in Safari and Firefox when Chrome seemed to work?

Firebase lists different cut-off versions for each browser: its note says a fix was already required on Firefox 109+ and Safari 16.1+ before Chrome M115+ joined on June 24, 2024. Any of them can show this error when the app and authDomain are on different sites.

Will changing authDomain break my Android or iOS build?

The authDomain field is documented as the domain that handles OAuth redirects on web platforms. The kIsWeb check in the code above applies the override only to the web build.

Is signInWithPopup always the answer?

It avoids the cross-site redirect, but Firebase notes popups can be blocked and are less smooth on mobile. If you need the redirect, use Fix B.

Sources

  1. Best practices for using signInWithRedirect on browsers that block third-party storage access (Firebase)
  2. Federated identity & social sign-in, Flutter (Firebase)
  3. Add Firebase to your Flutter app (Firebase)
  4. Authenticate with Firebase using email link: authorized domains (Firebase)
  5. FirebaseOptions.authDomain (pub.dev)
  6. FirebaseOptions.copyWith (pub.dev)
  7. FirebaseAuth.signInWithPopup (pub.dev)
  8. FirebaseAuth.getRedirectResult (pub.dev)
  9. google_sign_in package (pub.dev)
  10. google_sign_in_web package (pub.dev)
  11. Upcoming security changes to Google's OAuth 2.0 authorization endpoint in embedded webviews (Google Developers Blog)
  12. firebase-js-sdk issue #4256: missing initial state (GitHub)
  13. firebase-android-sdk issue #7379: Redirect URL not working properly on android (GitHub)
  14. MDN: Window.open() and popup blockers
  15. 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