Firebase Authentication is not persisted on Flutter Web

Issue

I am using Firebase Authentication on my Flutter Web app, but the session is not persisted during refresh.

This is the package I am using.

https://pub.dev/packages/firebase

This is how I am authenticating with Firebase

  static Future<User> handleSignInEmail(String email, String password) async {
    await init();

    final UserCredential userCredential =
        await auth().signInWithEmailAndPassword(email.trim(), password);

    assert(userCredential.user != null);
    assert(await userCredential.user.getIdToken() != null);

    final User currentUser = await userCredential.user;
    assert(userCredential.user.uid == currentUser.uid);

    print('signInEmail succeeded: $userCredential.user');

    return userCredential.user;
  }

If I refresh the page and call the following method, the user that is returned is null:

  static Future<User> getFirebaseUser() async {
    await init();
    return await auth().currentUser;
  }

A similar implementation using Flutter Mobile works as expected. What am I missing on the Flutter Web implementation?

Solution

Login happens automatically and it is handled by Firebase, however in async way. More details can be found in the official documentation:

https://firebase.google.com/docs/auth/web/auth-state-persistence

The trick is very simple. You need to wait for the first state change.

  static Future<User> getFirebaseUser() async {
    await init();
    //return await auth().currentUser;
    return await auth().onAuthStateChanged.first;
  }

It returns null if there is no signed-in user:
https://firebase.google.com/docs/reference/js/firebase.auth.Auth.html#onauthstatechanged

My firebase version:

firebase: 5.0.4 #https://pub.dartlang.org/packages/firebase

I wrote this implementation which works on both mobile and web:

  static Future<FirebaseUser> getFirebaseUser() async {
    FirebaseUser firebaseUser = await FirebaseAuth.instance.currentUser();
    if (firebaseUser == null) {
      firebaseUser = await FirebaseAuth.instance.onAuthStateChanged.first;
    }
    return firebaseUser;
  }

Answered By – Gedeon Gaal

Answer Checked By – David Marino (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *