我正在尝试检查用户是否已登录。即使用户已登录,它也会返回 false 值,尽管它应该返回 true。
isUserLoggedIn() {
bool? loggedIn = false;
FirebaseAuth.instance.authStateChanges().listen((User? user) {
if (user != null) {
print("True is getting executed.");
loggedIn = true;
}
});
print("Logged In Value: $loggedIn");
return loggedIn;
}
下面显示的是上面代码的输出:
I/flutter (18584): Logged In Value: false
I/flutter (18584): false
I/flutter (18584): True is getting executed.
我不确定为什么语句 True is getting executed.
最终会被打印出来。
谁能帮我解决这个问题?提前致谢。
答案 0 :(得分:1)
正如@luk2302 的评论所说:首先,您获取以 (User? user)
开头并以 });
结尾的代码块,您不运行它,您只需将其交给 FirebaseAuth,并询问 FirebaseAuth:“嘿,当 auth 状态改变时,你能运行这段代码吗?谢谢!”。
然后,在提交代码后立即检查登录值 false
,一段时间后,FirebaseAuth 运行您提交的代码。此代码将 loggedIn
设置为 true
,这完全没有用,因为您的 isUserLoggedIn
方法早已返回。
要修复它,您需要将代码移动到 listen()
块中。
不幸的是,您不能在这里这样做:您不能将 return
语句移动到这样的闭包中。
因此,我们需要扩大我们的视野:您编写的调用 isUserLoggedIn
的代码是什么?该假定对返回的值执行某些操作,例如,它会显示“登录失败”提示或类似提示。
THAT 代码需要移动到 listen
块中。这意味着您希望您的 isUserLoggedIn 方法根本不返回任何内容,而是将一段代码作为参数,然后您可以执行该代码块(传递它是真/假,或者可能是更好的 API 设计,获得两个代码块,一个登录成功时运行,登录失败时运行。
这被称为“回调地狱”。顾名思义,这很可怕——你最终将所有方法都写成不返回任何内容,并将一段代码作为参数,一旦信息可用,就会运行该代码块。您的所有代码都是一个无穷无尽的代码块链,任何试图找出代码执行位置的尝试都是一场灾难。
许多语言都有“回调地狱”的解决方案。 Here is one blog post about using the concept of a future instead - 如果您只是在网上搜索“飞镖回调地狱”,您可以找到更多。