问题
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
回答1:
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
回答2:
Calling User.reload()
reloads that user's profile data from the server.
A typical use-case for this is when you send an email to the user to verify their email address. When the user clicks the link in that email it goes back to the Firebase Authentication servers, which mark their email address as verified. But when this happens, there is no way for your app to know about it, since the call went straight from the email client to the server. So often you'll add a so-called continue URL to the link, which can call back into your app after the email address was verified. Then your app can call reload()
to load the updated state from the server.
回答3:
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.
firebaseAuth.userChanges().listen((user) {
// Your logic
});
回答4:
This is not a bug, but the weird way Firebase Auth works, and they say it won't change for now, so I made a package to fix this, grab it here: firebase_user_stream
In the Readme I explain the issues and how the package fixes them, there are examples and etc, enjoy!
回答5:
Maybe you need use .then or whenComplete in order to get the latest content, for example:
await _auth.updateProfile().then((retornedValueFromTheMethod) {
print(retornedValueFromTheMethod);
}).whenComplete(() {
print("TODO something if you want");
});
You need updateProfile be Future<retornedValueType> updateProfile() {...}
来源:https://stackoverflow.com/questions/51709733/what-use-case-has-the-reload-function-of-a-firebaseuser-in-flutter