Unfortunately, the redirection result is always null, which causes an infinite login loop (as my login is automatically on page load).
Firebase config on index.html
:
const firebaseConfig = {
apiKey: "A...zY",
authDomain: "private.pages.dev",
projectId: "p...79",
storageBucket: "p...79.firebasestorage.app",
messagingSenderId: "4...8",
appId: "1:...:web:...",
measurementId: "G-TN..."
};
Code that runs automatically after app initialization:
try {
// Check for redirect result
UserCredential? credential = await FirebaseAuth.instance.getRedirectResult();
print('credential: $credential');
if (credential.user != null) {
// Sign-in successful
print('Sign-in successful: ${credential.user}');
} else if (FirebaseAuth.instance.currentUser == null) {
print("initiating login");
// No user signed in, initiate sign-in
await FirebaseAuth.instance.signInWithRedirect(googleProvider);
}
// else {
// print("linking provider");
// // User is signed in but Google provider not linked, link the provider
// await FirebaseAuth.instance.currentUser!.linkWithRedirect(googleProvider);
// }
} on FirebaseAuthException catch (e) {
switch (e.code) {
case "provider-already-linked":
logger.i("The provider has already been linked to the user.");
break;
case "invalid-credential":
logger.i("The provider's credential is not valid.");
break;
case "credential-already-in-use":
logger.i(
"The account corresponding to the credential already exists, "
"or is already linked to a Firebase User.");
if (e.credential != null) {
await FirebaseAuth.instance.signInWithCredential(e.credential!);
}
break;
// See the API reference for the full list of error codes.
default:
logger.i("Unknown error.");
}
}
Console output:
credential: UserCredential(additionalUserInfo: null, credential: null, user: null)
initiating login
Navigated to https://p...79.firebaseapp.com/__/auth/handler?apiKey=A...zY&appName=%5BDEFAULT%5D&authType=signInViaRedirect&redirectUrl=https%3A%2F%2Fprivate.pages.dev%2F&v=10.11.1&providerId=google.com&customParameters=%7B%22login_hint%22%3A%22user%40example.com%22%7D&scopes=profile
GET https://p...79.firebaseapp.com/__/firebase/init.json 404 (Not Found)
Navigated to https://accounts.google.com/v3/signin/identifier?...
Navigated to https://private.pages.dev/
handler.js:63 Service Worker registration successful with scope: https://private.pages.dev/
credential: UserCredential(additionalUserInfo: null, credential: null, user: null)
initiating login
Navigated to https://p...79.firebaseapp.com/__/auth/handler?apiKey=A...zY&appName=%5BDEFAULT%5D&authType=signInViaRedirect&redirectUrl=https%3A%2F%2Fprivate.pages.dev%2F&v=10.11.1&providerId=google.com&customParameters=%7B%22login_hint%22%3A%22user%40example.com%22%7D&scopes=profile
... Repeating ...
As you can see, FirebaseAuth.instance.currentUser
is null, FirebaseAuth.instance.getRedirectResult()
is null, and there are no exceptions thrown.
So there were two issues:
When fireflutter stores configuration for firebase, you end up with some configuration duplicates over a few files. The main configuration is located at firebase_options.dart
. You do not need to store any configuration or initialize firebase on the index.html
, beyond the default:
<script src="flutter_bootstrap.js" async></script>
and the serviceworker registration for background FCM message processing, if you use it. Unless you use special features within the serviceworker, you can also
initialize it without the authDomain
configuration key - effectively limiting your authDomain
configuration to the firebase_options.dart
file.
When downloading the files for the redirection, the documentation points you to download the files like so:
mkdir signin_helpers/ && cd signin_helpers
wget https://<project>.firebaseapp.com/__/auth/handler
wget https://<project>.firebaseapp.com/__/auth/handler.js
wget https://<project>.firebaseapp.com/__/auth/experiments.js
wget https://<project>.firebaseapp.com/__/auth/iframe
wget https://<project>.firebaseapp.com/__/auth/iframe.js
wget https://<project>.firebaseapp.com/__/firebase/init.json
Some of the files are missing the .html
ending, which will prevent some hosts from serving it, or the browser from reading it correctly. Please don't realize it after banging the head against the wall for multiple hours like I did.