我对Flutter中的异步功能有疑问。我写了一个使用Firebase身份验证的代码。我想要使它在初始化状态功能处读取应用程序顶层(在这种情况下为“ Root Page”)的Firebase用户ID,然后将用户对象传递给它的子窗口小部件。由于检索用户ID的函数是异步函数,因此我遇到了一个问题,即子窗口小部件将获得用户ID的空值,即使它不应该为空。我已经在子代小部件中使用了将来的构建器,但是它不起作用。有谁知道如何正确地做到这一点。
我得到的确切错误是“构建函数返回null。令人讨厌的小部件是:FutureBuilder。构建函数绝不能返回null。”
RootPage(父级) _RootPageState类扩展了状态{
AuthStatus authStatus = AuthStatus.notSignIn;
String cuerrentUserId;
@override
void initState() {
super.initState();
widget.auth.currentUser().then((userId) {
setState(() {
authStatus = userId == null ? AuthStatus.notSignIn : AuthStatus.signIn;
cuerrentUserId = userId;
});
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new FutureBuilder<FirebaseUser>(
future: FirebaseAuth.instance.currentUser(),
builder: (BuildContext context, AsyncSnapshot<FirebaseUser> snapshot) {
switch(authStatus) {
case AuthStatus.notSignIn:
return new LoginPage(
auth: new Auth(),
onSignedIn: _signedIn,
);
case AuthStatus.signIn:
if (snapshot.connectionState == ConnectionState.done) {
return new HomePage(
auth: widget.auth,
onSignedOut: _signedOut,
userId: snapshot.data.uid,
);
}
else {
}
}
}
),
);
}
首页(子级)
Future<String> setUserData() async {
currentUser = User(widget.userId);
await currentUser.loadUserData();
_userName = currentUser.name;
_userEmail = currentUser.email;
_userPicURL = currentUser.avatar;
print('current user');
print(currentUser.id);
print(currentUser.email);
return _userName;
}
@override
Widget build(BuildContext context) {
return UserProvider(
user: currentUser,
child: new Container(
child: new FutureBuilder(
future: setUserData(),
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
if (snapshot.data!=null) {
...
答案 0 :(得分:0)
您可以使主要功能异步,以便在应用启动期间决定是否将登录名或主页显示为第一个屏幕。
如下所示:
Future<void> main() async {
FirebaseUser currentUser = await FirebaseAuth.instance.currentUser();
bool showHomePage = currentUser != null;
runApp(MyApp(showHomePage));
}
您现在可以使用showHomePage
中的MyApp
参数来确定最初应显示哪个屏幕。就是这样。
奖金:使用这种方法,您也无需显示摩擦屏幕即可被另一屏幕代替(例如显示主屏幕->用户未登录->替换为登录屏幕)。这看起来像是您应用程序中的一个小故障。