首页 > 解决方案 > 如何在 Flutter 中显示仍在从 Firestore 加载的数据?

问题描述

我正在尝试设置基本用户注册、登录、编辑个人资料、查看个人资料页面。目前注册、登录和编辑配置文件工作正常,我可以写信到 Firestore。但是我在检索数据时遇到了一些问题,我查看了有关如何检索数据的代码,但它不适用于我的代码。我有一个用户类,它获取用户的当前信息并设置一些变量,这样我只能从数据库中获取信息一次。但是,当我尝试在配置文件页面类中构造一个用户并获取信息时,会发生什么是它跳过了 get info 方法,因为它是异步的,因为嵌套在里面的 getCurrentUser 是异步的,因为 auth.currentuser 方法需要是异步的。

所以我明白问题出在哪里,我对其进行了测试,并在控制台中得到了证明这一点的值,但我该如何解决这个问题?我可以在我的代码中进行哪些更改才能在调用获取信息并返回 null 之前不跳过获取信息?我是新来的,所以如果这可能很明显,我很抱歉,非常感谢任何帮助,谢谢,

我的代码也可以从数据库中获取特定值,所以不要担心它是否不相关,因为它在控制台中正确显示,但在它异步后被跳过。

这些是我提到的在 User 类中存在的方法:

final _firestore = Firestore.instance;
  final _auth= FirebaseAuth.instance;
  FirebaseUser loggedInUser;

Future<void> getCurrentUser() async{
      try{
        final user= await _auth.currentUser();

        if(user!=null){
          loggedInUser=user;
          email=loggedInUser.email;
        }}
      catch(e){
        print(e);
      }
    }

    void getInfo() async {
        await getCurrentUser();
        DocumentReference documentReference =
        _firestore.collection("users").document("$email");
        documentReference.get().then((DocumentSnapshot datasnapshot) {
          if (datasnapshot.exists) {
            displayName=datasnapshot.data['displayName'].toString();
            bio=datasnapshot.data['bio'].toString();
            print(bio);
          }
          else {
            print("No such user");
          }
        });
      }

如您所见, getCurrentUser 需要是异步的。我有其他变量、方法和构造函数,但我尝试只共享需要显示的内容。

然后我在profilepagestate中有这段代码:

User currentUser;
  String bio;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    currentUser= new User();
    currentUser.getInfo();
    bio= currentUser.getBio();
  }

然后在个人资料页面的下方,我创建了一个文本小部件:

Text('$bio', style: TextStyle(fontSize: 30.0, ))

但是,文本总是在屏幕上显示 null,我明白发生了什么,但我不知道如何解决它。我尝试过改变事情,使事情不异步或至少尝试,但我无法弄清楚。请不要删除我的帖子,我环顾四周,这个问题是我的代码特有的,我真的不知道如何解决这个问题,我不想再浪费时间了。

标签: flutterdartgoogle-cloud-firestore

解决方案


您需要在数据仍在加载时显示替代小部件(通常是加载指示器)。

return bio == null
  ? CircularProgressIndicator()
  : Text('$bio', style: TextStyle(fontSize: 30.0, ));

更新

您的加载指示器卡住了,因为加载数据时您的页面永远不会重建。您需要setState在 currentUser 数据加载完成时调用来重建页面。

@override
void initState() {
  // TODO: implement initState
  super.initState();
  currentUser= new User();
  currentUser.getInfo().then((_) => 
    setState(() => bio = currentUser.getBio()));
}

为了能够链接调用,您需要将fromasync的返回值切换到。getInfo()voidFuture<void>

Future<void> getInfo() async {
  await getCurrentUser();
  // ..
}

推荐阅读