Futurebuilder 快照没有数据

Futurebuilder snapshot has no data

CollectionReference users = FirebaseFirestore.instance.collection('Users');
  FirebaseAuth auth = FirebaseAuth.instance;
  String uid = FirebaseAuth.instance.currentUser!.uid.toString();
  var userData;
  var dbFuture;

  @override
  void initState() {
    dbFuture = getData();
    super.initState();
  }

  Future getData() async {
    final String uid = FirebaseAuth.instance.currentUser!.uid.toString();
    final DocumentSnapshot doc = await users.doc(uid).get();
    users.doc(uid).get().then((DocumentSnapshot doc) {
      userData = doc.data();
      print(doc.data());
    });
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        body: FutureBuilder(
            future: dbFuture,
            builder: (context, snapshot) {
              if (snapshot.connectionState != ConnectionState.done) {
                return Container(
                  child: Text('waiting'),
                );
              }
              if (!snapshot.hasData) {
                return Container(
                  child: Text('error'),
                );
              }
              final data = snapshot.data;
              return Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text(userData['displayName']),
                    ElevatedButton(
                        onPressed: FirebaseAuth.instance.signOut,
                        child: Text("Log out"))
                  ],
                ),
              );
            }),
      );

我是 Flutter 的新手,正在尝试制作一个管理学院的应用程序。

我在 Firestore Cloud 成功保存了数据,我可以用

读取它们
      print(doc.data());

现在我想用这些数据构建个人资料页面,所以我使用了 Futurebuilder。

但是snapshot一直没有数据

我也看了documents,但还是不懂。

要从 Firebase 获取数据并将其显示在小部件中,您有两种方法,但您只能根据需要选择一种。

FutureBuilder()

此代码将调用您的数据库并在每次构建和每次 setState()(负责更新您的界面内容)时加载您请求的信息。它可能对某些数据类型有用,但在您的情况下,您的冗余 Firebase 调用可能会花费您。

CollectionReference users = FirebaseFirestore.instance.collection('Users');
  final auth = FirebaseAuth.instance;
  late final uid = auth.currentUser!.uid;

@override
  Widget build(BuildContext context) => Scaffold(
        body: FutureBuilder(
                future: users.doc(uid).get(),
                builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
                  if (snapshot.connectionState == ConnectionState.waiting) {
                    return Container(
                      child: Text('waiting'),
                    );
                  }
                  if (!snapshot.hasData) {
                    return Container(
                      child: Text('error'),
                    );
                  }

                  return Center(
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Text(snapshot.data!['some_data']),
                        Text(auth.currentUser?.displayName ?? 'user have no name'),
                        ElevatedButton(
                            onPressed: auth.signOut,
                            child: Text("Log out"))
                      ],
                    ),
                  );
                }),
      );

initState()

使用initState()时,里面的代码只调用一次。要刷新内容,您必须手动调用 getData()(例如 setState()

CollectionReference users = FirebaseFirestore.instance.collection('Users');
  final auth = FirebaseAuth.instance;
  late final uid = auth.currentUser!.uid;

  String? someData;

  @override
  void initState() {
      getData();
    super.initState();
  }

  Future<void> getData() async {
    users.doc(uid).get().then((doc) {
      someData = doc['some_data'];
    });
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(someData ?? 'no data'),
            Text(auth.currentUser?.displayName ?? 'user have no name'),
            ElevatedButton(
                onPressed: auth.signOut,
                child: Text("Log out"))
          ],
        ),
      ),
    );

最后,如果您的用户进行身份验证,您可以使用 auth.currentUser?.displayNameauth.currentUser!.updateDisplayName('new name') 来简单地获取和更改您的用户名。