Flutter & Firebase 将 10 多个 Firebase 文档放入 Stream<List<Map>>

Posted

技术标签:

【中文标题】Flutter & Firebase 将 10 多个 Firebase 文档放入 Stream<List<Map>>【英文标题】:Flutter & Firebase Get more than 10 Firebase Documents into a Stream<List<Map>> 【发布时间】:2021-05-17 07:50:30 【问题描述】:

使用 Flutter 和 Firestore,我试图将 10 多个文档放入 Stream。我可以使用映射 QuerySnapshot 的集合上的 .where 子句来做到这一点。但是,10 个限制是一个杀手。

我在我的应用程序中使用提供程序包。因此,在 Flutter 中使用 StreamProvider 构建流时,我可以返回一个

    StreamStreamStream

我需要介于 1 和 2 之间的东西。

我有一个包含多达 500 个文档的集合,用户可以选择这 500 个文档的任意组合进行查看。用户组装班级名册以查看他们的用户列表。

所以我正在寻找一种方法来获取单个流,例如 30 个文档,然后将它们编译成一个列表:但我需要这个 List

所以,我目前的努力:

  Future<Stream<List<AttendeeData>>> getStreams() async 
    List<Stream<AttendeeData>> getStreamsOutput = [];
    for (var i = 0; i < teacherRosterList.length; i++) 
      Stream thisStream = await returnTeacherRosterListStream(facility, teacherRosterList[i]);
      getStreamsOutput.add(thisStream);
    
    return StreamZip(getStreamsOutput).asBroadcastStream();
  

感觉我在下面作弊:如果我将快照直接放在上面的 Stream thisStream 中,我会收到等待错误,因为如果我等待,Stream 就不是未来,如果我不等待,它会移动得太快并得到一个空错误。

  Future<Stream<AttendeeData>> returnTeacherRosterListStream(String thisFacility, String thisID) async 
    return facilityList.doc(thisFacility).collection('attendance').doc(thisID).snapshots().map(_teacherRosterListFromSnapshot);
    
  

我如何在 _teacherRosterListFromSnapshot 中映射的示例(这里没有任何问题):

  AttendeeData _teacherRosterListFromSnapshot(DocumentSnapshot doc) 
    // return snapshot.docs.map((doc) 

    return AttendeeData(
      id: doc.data()['id'] ?? '',
      authorCreatedUID: doc.data()['authorCreatedUID'] ?? '',
   );
  

我的 StreamProvider 逻辑和错误:

return MultiProvider(
            providers: [
              StreamProvider<List<AttendeeData>>.value(
                  value: DatabaseService(
                teacherRosterList: programList,
                facility: user.claimsFacility,
              ).getStreams()),
            ]

错误:参数类型“Future>”无法分配给参数类型“Stream”。

AttendeeData 是我的地图类名称。

所以,问题总结:

    我什至可以这样做吗?我基本上是在流式传输地图流列表......这是一回事吗? 如果可以,我该怎么做? 一种。我无法将它放入 StreamProvider,因为 getStreams 是 Future...我该如何克服这个问题?

我可以使用 StreamProvider 的另一种方法获取数据,但它的行为不像 Stream 并且状态没有更新。我希望把它放到 Provider 中,因为我在那里很舒服,而且我可以很容易地管理状态。但是,乞丐不能挑剔。

【问题讨论】:

【参考方案1】:

我自己解决了这个问题,由于缺乏良好的开始和结束的答案,我为追随我的可怜的灵魂提供了我的例子,他们试图自己学习这些东西。我是初学者,所以这是一个艰难的过程:

目标: 您在集合中有任意数量的文档,并且您希望按文档编号提交任意数量的文档列表,并返回这些映射文档列表的单个流。您想要超过 10 个(对 .where 查询的 Firestore 限制),少于所有文档......所以介于 QuerySnapshot 和 DocumentSnapshot 之间。

解决方案:我们将获得一个 QuerySnapshot 列表,我们将组合它们并映射它们并将它们作为单个流输出。所以我们得到了 10 个块(最大值),然后剩下一些奇数。我将我的插入到一个 Provider 中,这样我就可以随时随地获得它。

所以从我的提供者那里,我将其称为 Stream 值:

  Stream<List<AttendeeData>> filteredRosterList() 
    var chunks = [];
    for (var i = 0; i < teacherRosterList.length; i += 10) 
      chunks.add(teacherRosterList.sublist(i, i + 10 > teacherRosterList.length ? teacherRosterList.length : i + 10));
     //break a list of whatever size into chunks of 10.

    List<Stream<QuerySnapshot>> combineList = [];
    for (var i = 0; i < chunks.length; i++) 
   combineList.add(*[point to your collection]*.where('id', whereIn: chunks[i]).snapshots());
     //get a list of the streams, which will have 10 each.

    CombineLatestStream<QuerySnapshot, List<QuerySnapshot>> mergedQuerySnapshot = CombineLatestStream.list(combineList);
    //now we combine all the streams....but it'll be a list of QuerySnapshots.

    //and you'll want to look closely at the map, as it iterates, consolidates and returns as a single stream of List<AttendeeData>
    return mergedQuerySnapshot.map(rosterListFromTeacherListDocumentSnapshot);
  

以下是我如何映射它以供您参考(为简洁起见,删除了所有字段):

  List<AttendeeData> rosterListFromTeacherListDocumentSnapshot(List<QuerySnapshot> snapshot) 
    List<AttendeeData> listToReturn = [];
    snapshot.forEach((element) 
      listToReturn.addAll(element.docs.map((doc) 
        return AttendeeData(
          id: doc.data()['id'] ?? '',
          authorCreatedUID: doc.data()['authorCreatedUID'] ?? '',
        );
      ).toList());
    );
    return listToReturn;
  

【讨论】:

以上是关于Flutter & Firebase 将 10 多个 Firebase 文档放入 Stream<List<Map>>的主要内容,如果未能解决你的问题,请参考以下文章

Flutter & Firebase - Firebase Analytics setUserProperty for Anonymous users

Flutter & Firebase:如何检查某个项目是不是存在于 Firebase 文档中的数组中

Flutter & firebase - StreamBuilder 未加载

Flutter 2 - firebase_remote_config 0.6.0 & firebase_core ^0.7.0 版本冲突

Flutter & Firebase - 从文档中获取特定字段

Flutter Firebase 上传自定义类列表