Flutter-如何从Firestore返回当前用户

时间:2019-01-17 21:36:20

标签: asynchronous dart flutter firebase-authentication google-cloud-firestore

尝试从现有的Firestore用户文档中检索经过身份验证的用户详细信息时,出现以下错误:

  

getter'uid'在null上被调用

我的代码如下:

    class SideDrawer extends StatelessWidget {
      const SideDrawer({Key key, this.user}) : super(key: key);
      final FirebaseUser user;

      @override
      Widget build(BuildContext context) {
        return ......
              ......
              userPanel(context),
              ......
      }

      Widget userPanel(BuildContext context) {
        return new Padding(
          padding: const EdgeInsets.only(top: 10.0),
          child: new DrawerHeader(
            child: StreamBuilder<DocumentSnapshot>(
              stream: Firestore.instance
                  .collection('users')
                  .document(user.uid)
                  .snapshots(),
              builder:
                  (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
                if (snapshot.hasError) {
                  return Text('Error: ${snapshot.error}');
                } else if (snapshot.hasData) {
                  return userName(snapshot.data);
                }
                return LinearProgressIndicator();
              },
            ),
          ),
        );
      }
    }

Text userName(DocumentSnapshot snapshot) {
  if (snapshot.data == null) {
    return Text('no data set in the user document in firestore');
  } else {
    return snapshot.data['name'];
  }
}

从登录页面发送用户:

  void signIn() async {
    if(_formKey.currentState.validate()){
      _formKey.currentState.save();
      try{
        FirebaseUser user = await FirebaseAuth.instance.signInWithEmailAndPassword(email: _email, password: _password);
        Navigator.push(context, MaterialPageRoute(builder: (context) => HomePage(user: user)));
      }catch(e){
        print(e.message);
      }
    }
  }
}

这是我的主页:

class HomePage extends StatelessWidget {
  const HomePage({Key key, this.user}) : super(key: key);
  final FirebaseUser user;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home'),
      ),
      drawer: SideDrawer(),
    );
  }
}

猜到这是一个异步编程问题,我对此进行了搜索,发现很少使用“ Future”对象的解决方案,但无法弄清楚如何以正确的方式实现它,请帮忙吗?

1 个答案:

答案 0 :(得分:2)

如果您使用的是Future,我猜您在调用SideDrawer时该用户为null,因此必须先添加验证,然后才能使用'user'对象。

 Widget userPanel(BuildContext context) {
            return new Padding(
              padding: const EdgeInsets.only(top: 10.0),
              child:  user != null ? DrawerHeader(
                child: StreamBuilder<DocumentSnapshot>(
                  stream: Firestore.instance
                      .collection('users')
                      .document(user.uid)
                      .snapshots(),
                  builder:
                      (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
                    if (snapshot.hasError) {
                      return Text('Error: ${snapshot.error}');
                    } else if (snapshot.hasData) {
                      return userName(snapshot.data);
                    }
                    return LinearProgressIndicator();
                  },
                ),
              ) : Center(child: CircularProgressIndicator(),)
            );

        }

在HomePage上的SideDrawer小部件上传递用户对象

  SideDrawer(user: user),

也请修复此行:

 return snapshot.data['name'];

应该是:

  return Text(snapshot.data['name']);