【问题标题】:Flutter Futurebuilder snapshot has no dataFlutter Futurebuilder 快照没有数据
【发布时间】:2021-11-17 17:41:12
【问题描述】:

在我的应用程序中第一次登录后,我想使用 Futurebuilder 获取用户数据。因此,我想从 firestore 获取数据并将值存储在静态 Helper 类中:

/// Helper Class
class UserManager {
  static Map<String, dynamic> userdata = null;
}

class FireBaseHandler {

  final CollectionReference usersCol = FirebaseFirestore.instance.collection(
      'users');
  final myUser = FirebaseAuth.instance.currentUser;

  /// fetch UserData
  Future getUserData() async {
    try {
      await usersCol
          .doc(myUser.uid)
          .get().then((value) => UserManager.userdata = value.data());
      return UserManager.userdata;
    } catch (e) {
      print(e.toString());
    }
  }
}

      /// Futurebuilder in main Code

      FireBaseHandler handler = FireBaseHandler();
      return FutureBuilder(
                      future: handler.getUserData(), /// get userData and store it in Helper class
                      builder: (context, userDataSnapshot) {
                        if (userDataSnapshot.hasData) {
                          print(UserManager.userdata);
                          return HomeScreen();
                        } else {
                          return Scaffold(
                            body: Center(
                              child: CircularProgressIndicator(),
                            ),
                          );
                        }
                      });

问题是来自 Futurebuilder 的快照永远不会有数据,因此userDataSnapshot.hasData 永远不会为真,它会停留在加载屏幕中。只有当我热重载快照有数据并且我进入主屏幕时。有什么问题?

【问题讨论】:

    标签: flutter dart future flutter-futurebuilder


    【解决方案1】:

    我认为问题在于您在 then (() {...}) 内部的 lambda 函数中初始化 UserManager.userdata 的方式此初始化是此函数的本地,原因为什么 UserManager.userdata 仍然是 null 尝试按照以下示例进行操作:

      Future getUserData() async {
         UserManager.userdata = (await usersCol.doc(myUser.uid).get()).data();
         return UserManager.userdata;
        
      }
    

    我认为UserManager.userdata 的值将仅在getUserData() 中可用
    如果你想在另一个类中使用UserManager.userdata,我猜它会为null,

    下面的好方法,你的函数只需要返回

      Future<Map<String, dynamic>> getUserData() async {
        return  (await usersCol.doc(myUser.uid).get()).data();
      }
    

    【讨论】:

      【解决方案2】:

      不要将async / await.then 混用,它们的作用相同,但两种语法不能混用。还要为您的Future 函数设置适当的数据类型并返回数据库获取的结果。你真的不需要try/catch,你会处理FutureBuilder中的错误:

      Future<Map<String, dynamic>> getUserData() async {
          return await usersCol.doc(myUser.uid).get();
      }
      
      return FutureBuilder(
        future: handler.getUserData(), /// get userData and store it in Helper class
        builder: (context, userDataSnapshot) {
          if (userDataSnapshot.hasError) {
              return const Text('Error');
          }
          if (userDataSnapshot.hasData) {
            if (!snapshot.data!.exists) {
              return const Text('Document not found');
            }
            else {
              UserManager.userdata = userDataSnapshot.data!.data();
              print(UserManager.userdata);
              return HomeScreen();
            }
          }
          // still loading
          else {
            return Scaffold(
              body: Center(
                child: CircularProgressIndicator(),
              ),
            );
          }
        });
      

      【讨论】:

        猜你喜欢
        • 2020-04-12
        • 2020-07-20
        • 2020-12-27
        • 2021-12-26
        • 2021-07-01
        • 1970-01-01
        • 2021-01-02
        • 2020-05-01
        • 2021-11-23
        相关资源
        最近更新 更多