为简单起见,假设我有两个屏幕:
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
中提取出来?
答案 0 :(得分:0)
我真的很喜欢这个问题,您让我重新考虑如何编写应用程序,现在我想知道是否还有更好的方法。谢谢你!
我认为从根本上讲,这个问题是与从UI(当前加载的页面)中分离出业务逻辑(流中的数据)有关。
我将考虑使用Provider并创建一项服务,以提供应用程序中任何小部件都可以访问的流。这样,您就可以使用一个服务来监听更改,更新数据,并且应用程序中的所有其他内容都可以监听该流。
这是您要找的吗?
编辑
您是否正在为侦听数据库更改的流付费?
答案是,“取决于”,来自Cloud Fire-Store Billing documentation。
收听查询结果
Cloud Firestore允许您收听查询结果并在查询结果更改时获取实时更新。
当您收听查询结果时,每次在结果集中添加或更新文档时,您都要付费。当文档从结果集中删除时,由于文档已更改,也会向您收费。 (相反,删除文档后,您无需支付阅读费用。)
此外,如果侦听器断开连接超过30分钟(例如,如果用户下线),则将向您收取读取费用,就好像您发出了全新的查询一样。