flutterfirebasefirebase-authenticationstreamstream-builder

Flutter Firebase: how to update user in UI


I want my App's UI to update whenever I change something about the currently signed in User, such as changing the displayName property. As you can see, I am using a StreamProvider and the Stream<User> object which is returned by FirebaseAuth.instance.idTokenChanges().
Is there a way for me to manually (I mean from my code) add a new event to that Stream, so that the whole UI of the app updates?

//Somewhere at the top of my app I have this widget:
class FirebaseAuthWrapper extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<User>.value(
      value: AuthHelper.userStream,
      initialData: AuthHelper.currentUser,
      child: App(),
    );
  }
}


class AuthHelper {
  static final FirebaseAuth _auth = FirebaseAuth.instance;
  static User get currentUser => _auth.currentUser;
  static Stream<User> get userStream => _auth.idTokenChanges();

  //...

  static Future<void> updateDisplayName(String newDisplayName) async {
    await currentUser.updateDisplayName(newDisplayName);
    //TODO how do I get the updated user object (with the updated displayName) to show in UI?
  }

  //...

}

Note: I HAVE solved this, but with a workaround. What I want to know is, is there a simpler, more straight-forward way of solving my problem?


Solution

  • FirebaseAuth.instance.idTokenChanges() executes in the following cases, see documentation:

    Events are fired when the following occurs:

    • Right after the listener has been registered.
    • When a user is signed in.
    • When the current user is signed out.
    • When there is a change in the current user's token.

    As you see, this does not include changes in displayName property. But there is another method which you can use, FirebaseAuth.instance.userChanges(), see documentation. With this you can listen to the following changes:

    Events are fired when the following occurs:

    • Right after the listener has been registered.
    • When a user is signed in.
    • When the current user is signed out.
    • When there is a change in the current user's token.
    • When the following methods provided by FirebaseAuth.instance.currentUser are called:
      • reload()
      • unlink()
      • updateEmail()
      • updatePassword()
      • updatePhoneNumber()
      • updateProfile()

    Now the documentation seems to be outdated, since updateProfile is deprecated in the most recent version of Firebase tools. The deprecation warning says:

    Use updatePhotoURL and updateDisplayName instead.

    Based on the comment from the author of OP, it is confirmed that userChanges is called when updateDisplayName is executed, so this solves the problems. In your code, instead of this:

    static Stream<User> get userStream => _auth.idTokenChanges();
    

    use this:

    static Stream<User> get userStream => _auth.userChanges();