使用 StreamBuilder 和从 Firebase Firestore 数据库查询时,ListView 不会更新/获取数据

Posted

技术标签:

【中文标题】使用 StreamBuilder 和从 Firebase Firestore 数据库查询时,ListView 不会更新/获取数据【英文标题】:ListView doesn't update/get data when using StreamBuilder and Querying from Firebase Firestore database 【发布时间】:2020-06-14 08:24:22 【问题描述】:

我正在尝试从特定集合 users 中检索数据,如下面的代码所示,但是当我查询此集合中的用户时,列表视图不显示。换句话说,它只显示一个 CircularProgressIndicator() 表示没有数据可以找到。在我注释掉 where 查询的那一刻,listview 完美呈现。

        backgroundColor: MyApp.backgroundColor,
        body: StreamBuilder<QuerySnapshot>(
          stream: _firestore
              .collection('users')
//            .where("chapter", isEqualTo: chapter)
              .orderBy('count', descending: true)
              .snapshots(),
          builder: (context, snapshot) 
            if (!snapshot.hasData)
              return Center(child: CircularProgressIndicator());
            return ListView.builder(
              itemExtent: 80.0,
              itemCount: snapshot.data.documents.length,
              itemBuilder: (context, index) =>
                  _buildListItem(context, snapshot.data.documents[index]),
            );
          ,
        ),
      );

我尝试将 Nested StreamBuilders 和 FutureBuilder 与 Streambuilder 结合使用,但这些解决方案都不起作用。对于这样一个关键特性,必须有一个简单的解决方案。

请告诉我如何同时查询和使用 StreamBuilder。

【问题讨论】:

您是否在任何地方检查流的错误?如果没有,您应该这样做,因为您的查询可能会失败,并且错误会为您提供更多详细信息。 嗨,我发现了问题!我用 StreamBuilder 包裹了一个 FutureBuilder 并且成功了! 很高兴听到您发现了问题。您想发布您的工作代码和更改的解释作为答案吗?这样人们就可以看到您是如何解决问题的,并且随着时间的推移,您可能会赢得一些声誉。 没问题!现在添加 【参考方案1】:

如下面的代码 sn-p 所示,这里的技巧是用 FutureBuilder 包装 StreamBuilder。如果您想要执行任何涉及需要时间获取的查询,您需要一个 FutureBuilder。在我的情况下,需要加载 chapter 以便列表视图可以查询它。列表视图未使用数据更新的原因是当列表视图尝试呈现时章节为空。

注意:如果您要查询提前知道的内容,则不需要 FutureBuilder。我为硬编码的章节测试了这个,它运行良好。

return FutureBuilder(
        future: _loadChapter(),
          builder: (context, snapshot) 
            return Scaffold(
              backgroundColor: MyApp.backgroundColor,
              body: StreamBuilder<QuerySnapshot>(
                stream: _firestore
                    .collection('users')
                    .where("chapter", isEqualTo: chapter)
                    .orderBy('count', descending: true)
                    .snapshots(),
                builder: (context, snapshot) 
                  if (!snapshot.hasData)
                    return Center(child: CircularProgressIndicator());
                  return ListView.builder(
                    itemExtent: 80.0,
                    itemCount: snapshot.data.documents.length,
                    itemBuilder: (context, index) =>
                        _buildListItem(context, snapshot.data.documents[index]),
                  );
                ,
              ),
            );
          
      );

以下是 loadChapter 方法的外观,以供参考。

 Future<void> _loadChapter() async 
    return await _populateCurrentUser(loggedInUser);
  

_populateCurrentUser(loggedInUser) 本质上是找到与当前登录用户链接的文档并填充全局变量,例如章节

【讨论】:

以上是关于使用 StreamBuilder 和从 Firebase Firestore 数据库查询时,ListView 不会更新/获取数据的主要内容,如果未能解决你的问题,请参考以下文章

来自一个 StreamBuilder 的 Flutter 快照显示在另一个 StreamBuilder 中

在 StreamBuilder 中使用 AnimatedList

使用 StreamProvider 和 StreamBuilder 时出错

使用 Firestore 和 Flutter 填充 DataTable(使用 StreamBuilder)

FutureBuilder 与 Streambuilder

在 Streambuilder 中的集合上使用 where() 不断返回 null