哪种用例在扑朔迷离中具有FirebaseUser的reload()函数?

时间:2018-08-06 14:16:43

标签: firebase dart firebase-authentication flutter

FirebaseUser的.reload()方法用于什么?
该函数在本地不会更改任何数据,并且使用Firestore.instance.currentUser()可以始终获取当前数据,对吗?

从文档中

  

重新加载公共任务()   手动刷新当前用户的数据(例如,附加的提供程序,显示名称等)。

所以我最初认为在调用user.reload()之后,输出将是:“用户名:bar”,而不是“用户名:foo”。 所以对我来说似乎什么都没做?

相关的附带问题
这也意味着我总是必须调用FirebaseAuth.instance.currentUser()以确保必须具有用户的当前信息?没有办法拥有FirebaseUser流,当用户信息更改时,该流会发出新的FirebaseUser吗? (我不是说Firebase.instance.onAuthStateChanged())

示例:

 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
  }

控制台输出:

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

5 个答案:

答案 0 :(得分:2)

呼叫User.reload()将从服务器重新加载该用户的配置文件数据。

典型的用例是您send an email to the user to verify their email address。当用户单击该电子邮件中的链接时,它将返回到Firebase身份验证服务器,该服务器将其电子邮件地址标记为已验证。但是,发生这种情况时,您的应用程序将无法知道它,因为该调用是直接从电子邮件客户端发送到服务器的。因此,通常您会在链接中添加一个所谓的continue URL,该链接可以在验证电子邮件地址后回调到您的应用程序中。然后,您的应用可以调用reload()从服务器加载更新的状态。

答案 1 :(得分:1)

允许您验证电子邮件而无需注销,然后再次登录。但是这可能是一个错误,但是当您调用user.reload()时,您必须再次调用currentUser()。

这不起作用:

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

您需要:

await user.reload();
user = await _auth.currentUser();
user.isEmailVerified => now it is true

答案 2 :(得分:0)

这不是错误,但是Firebase Auth的工作方式很奇怪,他们说它暂时不会更改,因此我制作了一个程序包来修复此问题,请在此处获取:firebase_user_stream

在自述文件中,我解释了这些问题以及软件包如何解决它们,还有示例等,请尽情享受!

答案 3 :(得分:0)

也许您需要使用.then或whenComplete来获取最新内容,例如:

await _auth.updateProfile().then((retornedValueFromTheMethod) {
  print(retornedValueFromTheMethod);
}).whenComplete(() {
  print("TODO something if you want");
});

您需要updateProfile为Future<retornedValueType> updateProfile() {...}

答案 4 :(得分:0)

这似乎是预期的行为。

就像已经说过的那样,仅呼叫.reload无效。

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

相反,您还必须再次获得currentUser

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

在返工(firebase_auth: ^0.18.0FirebaseAuth的同时也公开了.userChanges()流。 这似乎是首选的解决方案,而不是手动重新加载用户信息。

摘自FirebaseAuth.userChanges()的文档:

这是[authStateChanges]和[idTokenChanges]的超集。它 提供有关所有用户更改的事件,例如何时使用凭据 已链接,未链接以及何时更新用户配置文件。的 此Stream的目的是监听实时更新 用户无需手动调用[重新加载]然后补水 更改您的应用程序。

这还包括.isEmailVerified afaik。

firebaseAuth.userChanges().listen((user) {
  // Your logic
});