Flutter StreamBuilder中使用的Firestore快照在数据更改时永远不会更新

Posted

技术标签:

【中文标题】Flutter StreamBuilder中使用的Firestore快照在数据更改时永远不会更新【英文标题】:Firestore snapshot used in flutter StreamBuilder never gets updated when data changes 【发布时间】:2020-07-02 19:24:02 【问题描述】:

我是一个颤抖的菜鸟,试图用一些例子来工作。我创建了一个小部件,它使用 StreamBuilder 从 Firebase 中提取一些查询。它工作得很好,但是当数据发生变化时它永远不会更新 UI。我试着阅读它,从我所看到的一切来看,这应该是开箱即用的。我在 Firebase 方面是否缺少一些步骤来启用更改?或者 SteamBuilder 是否需要以某种方式进行配置,以便每隔一段时间提取一次数据? 代码是基本的,只是从一些示例中复制和粘贴:

@override
  Widget build(BuildContext context) 
    return StreamBuilder(
      stream: Firestore.instance
        .collection("XXX").orderBy('YYY')
        .where("userID", isEqualTo: userID)
        .snapshots(),
      builder: (BuildContext context, AsyncSnapshot snapshot) 
          if (!snapshot.hasData) 
            return Center(
              child: CircularProgressIndicator(
                valueColor: new AlwaysStoppedAnimation<Color>(
                  Color.fromRGBO(212, 20, 15, 1.0),
                ),
              ),
            );
           else 
            // Return some list view using the data in snapshot.data.documents
          
        
      );
    

[更新]:即使我更改查询,我的数据似乎也没有更新。我猜它正在使用一些本地缓存的数据,并且没有从服务器再次获取它。

[更新 2]:当我使用解析为无结果的查询(例如不存在的集合)时,纺车继续运行。再次运行正确的查询时,它会返回相同的旧结果,而不反映 Firebase 云中的任何更改。

[更新 3]:问题似乎与我的包含 orderBy 的流有关。一旦我删除一切正常。是bug吗??

【问题讨论】:

“我在 Firebase 方面是否缺少一些步骤来启用更改?”乍一看,您的代码看起来是正确的。 snapshots() 返回数据变化时更新的流,不需要额外配置。您可能希望 listen 到代码中其他位置的流,以查看 that 是否向您显示更新。如果是这样,您至少知道问题出在渲染中。 @FrankvanPuffelen 我在构建函数中添加了一些调试消息,就在渲染小部件之前 - 快照确实显示了旧信息,而不是数据库中的当前信息。我什至尝试重新启动应用程序,而不是热重载,但仍然是相同的旧数据。它似乎根本没有获得任何新数据(即使上面有我的第二次更新)...... 能否从build方法中提取整个Firestore代码,使用listen观察流,然后打印数据什么的。如果您可以重现该问题,请将您的问题更新为(仅)显示该代码及其输出。一旦我们可以排除渲染,就更容易提供帮助(尽管我马上不知道问题可能出在哪里)。 @FrankvanPuffelen 请参阅我的 [更新 3] - 问题似乎与 orderBy 成为流的一部分。如果我删除它,那么一切正常。这是我应该报告的错误还是我没有正确使用它? 如果没有我在以前的 cmets 中要求的测试,我将无法提供进一步的帮助。 【参考方案1】:

您需要使用whereorderBy 字段创建索引:

https://firebase.google.com/docs/firestore/query-data/indexing


  "collectionGroup": "XXX",
  "queryScope": "COLLECTION",
  "fields": [
    
      "fieldPath": "userId",
      "order": "ASCENDING"
    ,
    
      "fieldPath": "YYY",
      "order": "DESCENDING"
    
  ]
,

【讨论】:

我也认为这是发现这个问题后的问题:github.com/flutter/flutter/issues/15928。但即使使用单个 orderBy,它似乎也不起作用。当我为其添加索引时,它实际上并没有做任何事情,因为该索引已经自动创建。我还尝试了两个 orderBy 并添加了一个复合索引,但仍然得到旧结果...如果是索引错误,我不应该在某处看到错误消息吗? 好的,想通了。它需要是 where 和 orderBy 字段的复合索引。 @blaneyneil 如果您想将此添加到您的答案中,我会将其标记为实际答案。谢谢 刚刚更新以显示 firestore.indexes.json 示例

以上是关于Flutter StreamBuilder中使用的Firestore快照在数据更改时永远不会更新的主要内容,如果未能解决你的问题,请参考以下文章

FirebaseStorage + Flutter,streamBuilder?

在 Flutter 中使用 streamBuilder 时条件不起作用

Flutter:Streambuilder - 关闭流

Flutter Firebase 实时数据库 StreamBuilder 更新

如何在 Flutter 中使用 Firestone 的 streambuilder 获取嵌套文档?

Flutter:如何为 StreamBuilder 制作 http 流