Flutter:有关用于检索Firebase用户ID的异步函数的问题

时间:2018-10-28 15:44:40

标签: firebase flutter

App Flowchart

我对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) {    
...

1 个答案:

答案 0 :(得分:0)

您可以使主要功能异步,以便在应用启动期间决定是否将登录名或主页显示为第一个屏幕。

如下所示:

Future<void> main() async {
  FirebaseUser currentUser = await FirebaseAuth.instance.currentUser();
  bool showHomePage = currentUser != null;
  runApp(MyApp(showHomePage));
}

您现在可以使用showHomePage中的MyApp参数来确定最初应显示哪个屏幕。就是这样。

奖金:使用这种方法,您也无需显示摩擦屏幕即可被另一屏幕代替(例如显示主屏幕->用户未登录->替换为登录屏幕)。这看起来像是您应用程序中的一个小故障。