Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What use case has the reload() function of a FirebaseUser in flutter?

What is the method .reload() from the FirebaseUser used for?
Locally the function doesn't change any data, and with Firestore.instance.currentUser() i would always get the current data, wouldn't I?

From the docs:

public Task reload () Manually refreshes the data of the current user (for example, attached providers, display name, and so on).

So I originally thought after calling user.reload() the output would be: "name of user: bar" and not "name of user: foo". So for me it seems like it doesn't really do anything?

Related side-question:
Also that means that I always have to call FirebaseAuth.instance.currentUser() to be sure to have to current information of the user? There's no way to have a stream of FirebaseUser, which emits a new FirebaseUser when user information is changed? (I don't mean Firebase.instance.onAuthStateChanged() )

Example:

 static stackOverflowProblem() async {
    FirebaseUser user = await FirebaseAuth.instance.currentUser();
    print("Name of User: ${user.displayName}"); //prints foo

    //Renaming the name from "foo" to "bar"
    UserUpdateInfo userInfo = UserUpdateInfo();
    userInfo.displayName = "bar";
    await _auth.updateProfile(userInfo);

    print("\nBefore calling user.reload:");
    print("Name of user: ${user.displayName}"); //prints foo
    print("Name of FirebaseAuth.instance.currentUser: ${(await FirebaseAuth.instance.currentUser()).displayName}"); //prints bar

    await user.reload();

    print("\nAfter calling user.reload:");
    print("Name of user: ${user.displayName}"); //prints foo
    print("Name of FirebaseAuth.instance.currentUser: ${(await FirebaseAuth.instance.currentUser()).displayName}"); //prints bar
  }

Console output:

I/flutter (19989): Name of User: Foo
I/flutter (19989): 
I/flutter (19989): Before calling user.reload:
I/flutter (19989): Name of user: Foo
I/flutter (19989): Name of FirebaseAuth.instance.currentUser: bar
I/flutter (19989): 
I/flutter (19989): After calling user.reload:
I/flutter (19989): Name of user: Foo
I/flutter (19989): Name of FirebaseAuth.instance.currentUser: bar
like image 602
JSAN L. Avatar asked Aug 06 '18 14:08

JSAN L.


People also ask

How do you refresh a Firebase token?

You can refresh a Firebase ID token by issuing an HTTP POST request to the securetoken.googleapis.com endpoint. The refresh token's grant type, always "refresh_token". A Firebase Auth refresh token. The number of seconds in which the ID token expires.

What does createUserWithEmailAndPassword return?

The createUserWithEmailAndPassword() function returns a so-called Promise, which has methods catch() and then() . You're already using catch() to handle problems. To handle "non-problems", you need to use then() : firebase. auth().

What is UserCredential Flutter?

UserCredential class Null safetyA structure containing a User, an OAuthCredential and operationType. operationType could be 'signIn' for a sign-in operation, 'link' for a linking operation and 'reauthenticate' for a reauthentication operation.

How does authentication work in Flutter?

To use an authentication provider, you need to enable it in the Firebase console. Go to the Sign-in Method page in the Firebase Authentication section to enable Email/Password sign-in and any other identity providers you want for your app.


2 Answers

Lets you verify email without logging out, and logging in again. BUT it might be a bug, but when you call user.reload(), you have to call currentUser() again.

This does not work:

await user.reload();
user.isEmailVerified => still false

You need to:

await user.reload();
user = await _auth.currentUser();
user.isEmailVerified => now it is true
like image 145
Gabeloooooo Avatar answered Sep 23 '22 03:09

Gabeloooooo


This seems to be the intended behavior.

Like it was already said only calling .reload does not work.

await user.reload();
print(user.emailVerified) // false

Instead you also have to get the currentUser again.

await user.reload();
// `currentUser` is synchronous since FirebaseAuth rework
user = firebaseAuth.currentUser;
print(user.emailVerified) // true

With the rework (firebase_auth: ^0.18.0) FirebaseAuth does also expose a .userChanges()-Stream. This seems to be the preferred solution instead of manually reloading the user information.

From the documentation of FirebaseAuth.userChanges():

This is a superset of both [authStateChanges] and [idTokenChanges]. It provides events on all user changes, such as when credentials are linked, unlinked and when updates to the user profile are made. The purpose of this Stream is to for listening to realtime updates to the user without manually having to call [reload] and then rehydrating changes to your application.

This includes also .isEmailVerified afaik (edit: might not be true, see comments).

firebaseAuth.userChanges().listen((user) {
  // Your logic
});
like image 27
JSAN L. Avatar answered Sep 24 '22 03:09

JSAN L.