【问题标题】:Initialize object to show in my Scaffold初始化对象以显示在我的脚手架中
【发布时间】:2019-01-26 20:15:44
【问题描述】:

我正在开发一个 Flutter 应用,遇到一个问题就停下来了,希望你们能帮助我。

首先,英语不是我的第一语言,所以很抱歉有任何错别字。

我正在编写一个简单的“管理个人资料”屏幕。当用户在我的应用上注册时,我会向他展示一个 Scaffold,其中包含一些必须填写的字段,例如姓名、姓氏、电子邮件等。

我正在使用 Firestore 数据库,这就是我调用的异步方法来检索“用户”对象:

  Future<Usuario> getUsuarioLogado() async {
    Cartao cartao;
    String email = await auth.currentUser();
    String nome, sobrenome, cpf, numeroCartao, nomeCartao;

    DocumentReference usuarioReference =
        Firestore.instance.document('Usuarios/' + email);

    usuarioReference.get().then((datasnapshot) {
      if (datasnapshot.exists) {
        nome = datasnapshot.data['nome'];
        sobrenome = datasnapshot.data['sobrenome'];
        cpf = datasnapshot.data['cpf'];

        CollectionReference cartaoReference =
            Firestore.instance.collection('Usuarios/' + email + '/Cartao');

        cartaoReference.getDocuments().then((cartoes) {
          List listCartoes = cartoes.documents;
          nomeCartao = listCartoes[0].data['nome'];
          numeroCartao = listCartoes[0].data['numero'];

          cartao = new Cartao(nomeCartao, numeroCartao);
          return new Usuario(cpf, nome, sobrenome, email, cartao);
        }).catchError((e) {
          print('#ANTLOG_GET_CARTAO: ' + e);
        });
      }
      return new Usuario(cpf, nome, sobrenome, email, cartao);
    }).catchError((e) {
      print('#ANTLOG_GET_USUARIO: ' + e);
    });
  }

上面的代码在我调试时工作,但在我需要时它不返回对象。现在是我的屏幕正在构建自己的时刻。

在阅读了一些论坛后,我尝试返回一个 FutureBuilder,它只会在“Usuarios”(用户)不为空时显示内容。

return FutureBuilder<Usuario>(
  future: perfil.getUsuarioLogado(),
  builder: (BuildContext context, AsyncSnapshot<Usuario> snapshot) {
    if (snapshot.connectionState == ConnectionState.done) {
      print('#ANTLOG: ${snapshot.data}');
      return scaffold;
    } else
      return Text('Loading...');
  },
);

下面的代码给我一个空值:

print('#ANTLOG: ${snapshot.data}');

我想知道如何强制屏幕等到我拥有我的“Usuarios”对象。似乎 FutureBuilder 不工作或者我做错了什么。

我需要你的帮助。

【问题讨论】:

  • 尝试使用snapshot.connectionState == done 代替snapshot.hasData
  • @RémiRousselet,现在屏幕总是在Loading... 屏幕中
  • 您的加载很可能有错误。因此hasData 总是假的
  • 我的快照有时会检索数据,但调用了return 方法并且它没有数据。我可以添加一些侦听器来获取快照对象,以便我可以使用检索到的数据重新加载我的 Scaffold 吗?

标签: firebase firebase-realtime-database async-await flutter google-cloud-firestore


【解决方案1】:

FutureBuilder 有一个名为initialData 的属性,您可以使用它来放置您的初始空对象。

正如 Rémi Rousselet 提到的,您应该使用 snapshot.hasData 检查是否有可用数据

 if (snapshot.hasData) {
      print('#ANTLOG: ${snapshot.data}');
      return scaffold;
    } else
      return Text('Loading...');
  },

因为你的方法被标记为async,所以在usuarioReference.get()之前使用await关键字等待响应,这样你的代码将更具可读性。

 await usuarioReference.get()  ...

同样的

 await cartaoReference.getDocuments()

【讨论】:

  • 我不能在 FutureBuilder 的 Future 参数中使用 await 导致 Dart 抛出错误。
  • 最终数据快照 = 等待 usuarioReference.get(); //在你的方法中而不是使用 then()...
  • final 关键字并不重要,只是 await (FutureTask) ,而不是 (FutureTask).then ....
  • 你可以使用:var snapshot = await usuarioReference.get();它会工作
  • 没问题,尽可能观看此视频,您将了解有关 dart 中异步的更多信息:youtube.com/watch?v=MUDOIAssBDs
猜你喜欢
  • 2012-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
  • 2013-06-27
  • 1970-01-01
  • 2012-05-14
  • 1970-01-01
相关资源
最近更新 更多