Cloud Firestore 在流中等待未来 - 使用用户 ID 将用户加入文档

Posted

技术标签:

【中文标题】Cloud Firestore 在流中等待未来 - 使用用户 ID 将用户加入文档【英文标题】:Cloud Firestore await future within stream - join user to document using user id 【发布时间】:2021-12-07 12:40:46 【问题描述】:

我正在收听一个文档流,每个文档中都有一个 uid,我想用它来获取与该文档关联的用户配置文件。有点像加入,但在 Firestore 的情况下,只是获取用户配置文件,因此我将拥有与该文档关联的最新用户配置文件。由于获取用户配置文件将是一个返回未来的单独查询,我将如何在获取配置文件的同时获取我的流。到目前为止,我唯一可行的解​​决方案与多个流构建器下的嵌套未来构建器有关,但我需要一个更好的解决方案。下面是我的代码。

Stream<List<Tab>> get sentTabs 
return _db
    .collection('tabs')
    .where('sender', isEqualTo: user.uid)
    .snapshots()
    .map((list) => list.docs.map((doc) 
          Tab tab = Tab.fromJson(doc.data(), doc.id);
          // i'd like to fetch the associated user profile here // tab.shownUser = await getUser(tab.payerUID!);
          return tab;
        ).toList());

【问题讨论】:

所以你需要Stream.asyncMap(或Stream.asyncExpand)而不是Stream.map 差不多,但是这些地图方法不可用 snapshots() 方法返回一个Stream 那么Stream.asyncMap 怎么不可用呢? snapshots() 返回一个 Stream 但 list.docs 返回一个查询快照列表,我需要在其中获取关联的用户配置文件,或者您认为有更好的方法吗?跨度> 【参考方案1】:

我多次遇到同样的问题,我发现最有用的解决方案正是您提出的:在StreamBuilder 中使用FutureBuilder

Tab tab = Tab.fromJson(doc.data(), doc.id);
//Add a FutureBuilder
return FutureBuilder(
    future: getUser(tab.payerUID!),
    builder: (context, snapshot) 
      //your logic here
    
return tab;
)

后来为了使其更优化,我使用了 StreamProvider,因为我在代码的多个位置使用相同的流。

底线:没有魔法,你需要查询数据库两次。

【讨论】:

以上是关于Cloud Firestore 在流中等待未来 - 使用用户 ID 将用户加入文档的主要内容,如果未能解决你的问题,请参考以下文章

在流中停止自己的音频

在使用 Swift 的 iOS 应用程序中使用 DispatchQueue 等待数据从 Cloud Firestore 返回时遇到问题

防止在流中输入不需要的值

你啥时候在流中使用接口而不是类型别名?

java 按方法值在流中查找对象

C# 在流中添加 40 个字节