如何从QuerySnapshot中获取特定文档的DocumentSnapshot?

时间:2019-08-04 09:04:49

标签: flutter dart google-cloud-firestore snapshot

为简单起见,假设我有两个屏幕:

  • StoriesListScreen
  • StoryDetailsScreen

要填充StoriesListScreen,我可以使用Stream从Firestore中获取一些数据:

Stream<QuerySnapshot> getFirstTenStories() {
    return _firestore.collection('stories').limit(10).snapshots();
}

然后我在Stream的{​​{1}}中使用此StreamBuilder,并将其中包含的文档映射到某些StoriesListScreen对象。然后,我使用Story创建一个ListView.builder对象,并使用StoriesListTile对象作为参数,以便它们可以呈现列表中的每个对象。

一切都很好...

但是,当用户单击Story时,我想打开StoriesListTile并显示该特定StoryDetailsScreen对象的详细信息。

由于Story对象此时已存在并且已经传递到Story对象中,因此我可以轻松地将此StoriesListTile对象传递给Story:< / p>

StoryDetailsScreen

所以工作正常,但是...

我希望能够监听用于创建 Navigator.of(context).push(MaterialPageRoute(builder: (context) => StoryDetailsScreen(_story)); 对象的数据的任何变化。

此刻,如果我在Firestore中的数据发生更改,则Story中的列表将自动更新,因为它使用了StoriesListScreen

我想在Stream<QuerySnapshot>中做同样的事情,但是我传递给StoryDetailsScreen屏幕的不是StoryDetailsScreen,而是一个Stream对象,不会已更新。

一种解决方案可能是从Firestore获取故事数据,并在Story中的Stream<DocumentSnapshot>中使用StreamBuilder,因此如果数据更改,它将自动更新。但这意味着浪费另一个Firestore读取的内容,因为我已经有了这些数据。

那么如何将特定文档的StoryDetailsScreen传递给我的Stream<DocumentSnapshot>?是否可以从我已经拥有的StoryDetailsScreen中提取出来?

1 个答案:

答案 0 :(得分:0)

我真的很喜欢这个问题,您让我重新考虑如何编写应用程序,现在我想知道是否还有更好的方法。谢谢你!

我认为从根本上讲,这个问题是与从UI(当前加载的页面)中分离出业务逻辑(流中的数据)有关。

我将考虑使用Provider并创建一项服务,以提供应用程序中任何小部件都可以访问的流。这样,您就可以使用一个服务来监听更改,更新数据,并且应用程序中的所有其他内容都可以监听该流。

这是您要找的吗?

编辑

您是否正在为侦听数据库更改的流付费?

答案是,“取决于”,来自Cloud Fire-Store Billing documentation

收听查询结果

Cloud Firestore允许您收听查询结果并在查询结果更改时获取实时更新。

当您收听查询结果时,每次在结果集中添加或更新文档时,您都要付费。当文档从结果集中删除时,由于文档已更改,也会向您收费。 (相反,删除文档后,您无需支付阅读费用。)

此外,如果侦听器断开连接超过30分钟(例如,如果用户下线),则将向您收取读取费用,就好像您发出了全新的查询一样。