【问题标题】:Flutter not picking up firebase logout颤振没有拿起firebase注销
【发布时间】:2020-08-05 04:58:59
【问题描述】:

我正在尝试在 Flutter 中实现 Firebase 授权。我能够成功登录并导航到新屏幕,但是在尝试注销时,我看到 logcat 中的活动表明:

但是,我希望主页会根据此注销进行更新。也就是说,我有一个应该在登录和注销之间切换的图标,但应用程序似乎保持登录状态。这些是我期望出现在同一屏幕上的布局更改:

用户单击注销按钮,但我希​​望小部件更新为以下内容:

我要求注销的功能如下,并出现在我的主页小部件中

class _MainActivityState extends State<MainActivity> {

        var  userStatus = FirebaseAuth.instance.currentUser();


  Future logout()
  async{
     final FirebaseAuth auth = FirebaseAuth.instance;
     await auth.signOut();
Navigator.push(context,MaterialPageRoute(builder: (context) => MainActivity())
);


    return userStatus = null;
}

在我的代码中,我使用if 语句(如果我使用字符串手动覆盖登录/注销,则该语句有效)基于 userStatus 在小部件之间切换,如下所示:

if(userStatus != null)
                  Container(
//Some code here for the widget showing login button.
)

或者如果退出:

if(userStatus == null)
                  Container(
//Some code here for the widget showing login button
 )

我有一个单独的登录页面,我最初在其中执行了登录,但身份验证状态似乎对整个应用程序都保持不变。

我如何覆盖 Auth.signout() 似乎没有更新用户状态。

【问题讨论】:

  • 考虑使用任何状态管理技术,比如 MobX,这样你就可以让你的 UI 对退出等变化做出反应

标签: flutter dart firebase-authentication


【解决方案1】:

这可能是您将变量设置为FirebaseAuth.instance.currentUser(); 的问题,它返回一个 Future,但在构建您的小部件之前没有等待该值。因此,它不会为 null,而是等待完成的 Future 状态,因此您的条件永远不会正确评估 null。

为了解决这个问题,让我们在 initState 方法中初始化 userStatus,这样它就只用异步函数初始化一次,在 Future 完成后重建。然后在您的注销方法中调用此函数来重置 userStatus 并使用 setState 重建小部件:


var userStatus;
@override
void initState() {
    super.initState();
    setUserStatus();
}

Future<void> setUserStatus() async {
  userStatus = await FirebaseAuth.instance.currentUser();
  setState(() {});
}

Future<void> logout() async {
  await FirebaseAuth.instance.signOut();
  setUserStatus();
}

【讨论】:

  • 您还想看什么其他代码?我在 Future 函数中尝试了 setState,但它没有解决问题。注销请求似乎发送到了 firebase,但是如果您关闭应用程序并再次打开它,设备仍然显示为已登录。
  • 我刚刚更新了我的帖子,试试这个解决方案,看看它是否有效,至于关闭应用并打开它仍然处于登录状态,我认为它实际上不是用户正在登录,但是由于您将变量设置为 Future 值并检查它是否为 null 以显示已注销的 UI,因此在构建时它永远不会评估为 null
  • getUserStatus() 函数在哪里使用?
  • 糟糕,这是我的错字。它应该是 setUserStatus
  • 本质上,setUserStatus 在设置 userStatus 之前等待 currentUser() 函数完成,然后我们调用一个空的 setState 来重建小部件。
【解决方案2】:

使用此代码注销后:

final FirebaseAuth auth = FirebaseAuth.instance;
await auth.signOut();

为什么要导航到同一个活动(屏幕)?只需使用 setState 再次重建屏幕并在那里分配新的 userStatus:

setState(() { userStatus = null; });

【讨论】:

  • 我在玩各种选项,看看它是否会解决。我应该将setState 放在await auth.signout 行之后吗?
  • 我尝试了解决方案,但发生的情况是屏幕会在短时间内(0.5 秒)呈现注销小部件,然后恢复为登录小部件。
  • 是的,在成功注销后调用setState 函数并将其放入其回调userStatus = null; 中,该回调将在重建之前调用。在重建 UI 之前,userStatus 将为空,因此它应该显示注销按钮。
  • 我不知道为什么您的注销小部件只是短暂呈现。您必须共享更多代码。你有计时器之类的吗?
  • 您还想查看哪些其他代码。让我知道,我会更新问题?我没有计时器。但是一旦注销,为什么它会为用户仍然登录的视图运行小部件?
猜你喜欢
  • 2021-04-05
  • 1970-01-01
  • 2013-07-29
  • 2016-12-25
  • 2020-10-02
  • 1970-01-01
  • 1970-01-01
  • 2020-12-08
  • 2021-11-26
相关资源
最近更新 更多