Flutter:当内容从 Google Firestore 到达时如何更新小部件?

Flutter: How to update widgets when their content arrives from Google Firestore?

好的,我的任务是, 1. 从 Firestore 下载记录, 2. 将其处理成状态变量 3. 将数据注入小部件。

我尝试通过在 initState 中下载内容来执行此操作,我将其设为异步,但是在 Firestore 下载完成之前调用了构建方法,我没有为小部件准备好信息,它崩溃了。

我读到,当 Widget 在布局后预计会发生变化时,我应该为小部件使用 Builder 包装器。这让我想到了这个:

      Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
                title: Text(
                    "Job details")), // TODO might have to modify to accomodate edits
            body: _buildBody(context, widget.job.country, widget.job.area, widget.job.jobDetailedId, widget.job),
          );
}

所以我正在调用带有 Builder 上下文的 buildBody,似乎我无法访问我的 this.job class 对象(为什么?!)所以我传递了一些关键参数以获取 Firestore记录.

_buildBody 的目的是下载 firestore 记录,而不使用 ASYNC await。但它从不执行

以外的任何代码

.then((jobrecord {

Widget _buildBody(BuildContext context, String countryCode, String area, String jobDetailedId) {
  Job detailedJob;
  Firestore.instance.collection("$countryCode/$area/JobsDetailed").document(jobDetailedId).get().then((jobRecord) {
  return Builder(builder: (BuildContext context) {
      if(jobRecord == null) {
        return Text("Document doesn't exist");
      }
      else {
        detailedJob = Job.fromSnapshot(jobRecord);
        detailedJob.jobDetailedId = jobRecord.documentID;
        return _screenBuild(context, detailedJob);
      }
  });
  });
}

Widget _screenBuild(BuildContext context, Job detailedJob) {
  return Text(detailedJob.description);
}

我以为 .then 会在 Firestore 返回文档时触发,但它没有触发。

这是解决问题的最好、最清晰的方法吗?使用 Future 会更好吗?或者 Asnc await from initState(),然后使用 setState()?

这段代码应该可以完成工作。

Widget _buildBody(BuildContext context, String countryCode, String area, String jobDetailedId) {
  Job detailedJob;
    return StreamBuilder<DocumentSnapshot>(
          stream: Firestore.instance.collection("$countryCode/$area/JobsDetailed").document(jobDetailedId).snapshots(),
          builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(
                child: CircularProgressIndicator(),
              );
            } else {
              var jobRecord = snapshot.data.data; // contains document fields
              if(jobRecord == null) {
                return Text("Document doesn't exist");
              }
              else {
                detailedJob = Job.fromSnapshot(snapshot.data);
                detailedJob.jobDetailedId = jobRecord.documentID;
                return _screenBuild(context, detailedJob);
              }
            }
          });
}