如何在 firebase firestore 中合并多个流

How exactly to merge multiple streams in firebase firestore

在你说这是一个重复的问题或者我应该使用嵌套流构建器之前,请听我说完。

我正在设计社交媒体类型的应用程序。我希望用户在他们关注 post“我的关注者帖子”collection 时收到更新。 在应用程序中,应用程序将检查 firebase rtdb 以获取当前用户的关注列表(他关注的人)并列出他们的 uid。

我计划使用上述列表来创建一个流列表(当然是按时间排序)并将它们合并为一个流,然后将其馈送到私有提要页面上的流构建器中。

在此页面上,用户将能够轻松地关注他们感兴趣的人 posting。

我认为这样的系统比每个用户在“私人提要”collection 中拥有一份文档更经济高效,而且只要有人 post 有东西,应用程序就会读取他们的列表关注者,然后立即 post 在他们的每一个私人供稿中进行更新。 因为...想象一个拥有 200 万粉丝的人。即刻写入 200 万次。后来,200 万次阅读。 我认为 poster 只需将 post 放入他们的“publicFeed”中,不同的关注者只需收听该提要并与他们保持联系即可,这样成本效率更高。

但是.. 这需要实现多个流(超过 2 个)的合并。我该怎么做?

我试过阅读 RxDart,但它对我来说完全是希腊语。我是飞镖的初学者。我现在只编码了大约 5 个月。

我最近有一个类似的案例,我建议你这样做 (我正在使用 cloud firestore,但我确定您已经编写了流,所以重要的部分是多个流的使用):

您必须将此插件添加到发布 spec.yaml: https://pub.dev/packages/rxdart

这里是存储库(在你的情况下,帖子,比方说 newPosts,oldPosts):

class PostRepository {

  static CollectionReference get collection => yourCollectionRef;
    
  static Stream<List<Post>> newPosts() {
    Query query = collection
        .where('Your condition like was viewed', isEqualTo: false)
        .orderBy('updateDate', descending: true)
        .limit(50);
    return query.snapshots().map<List<Post>>((querySnapshot) {
      final _newPosts = querySnapshot.documents.map((doc) {
        final post = Post.fromDoc(doc);
        return post;
      }).where((p) => p != null);

      return _newPosts
    });
  }

  static Stream<List<Post>> oldPosts() {
    Query query = collection
        .where('Your condition like was viewed', isEqualTo: true)
        .orderBy('updateDate', descending: true)
        .limit(50);
    return query.snapshots().map<List<Post>>((querySnapshot) {
      final _oldPosts = querySnapshot.documents.map((doc) {
        final post = Post.fromDoc(doc);
        return post;
      }).where((p) => p != null);

      return _oldPosts
    });
  }
}

然后要获得多个流(上面的两个组合),请在您的小部件中这样做 class:

重要!你必须导入这个 - import 'package:rxdart/streams.dart';

List<Post> newPosts;
List<Post> oldPosts;

Widget _pageContent() {
  return SingleChildScrollView(
    child: Column(
      children: [
        ListView.builder(
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          itemCount: newPosts.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(newPosts[index].title)
            );
          }
        ),
        ListView.builder(
          shrinkWrap: true,
          physics: NeverScrollableScrollPhysics(),
          itemCount: oldPosts.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(oldPosts[index].title)
            );
          }
        )
      ]
    )
  );
}

Widget _posts() {
  return StreamBuilder(
    stream: CombineLatestStream.list([
      PostRepository.getNewPosts(),
      PostRepository.getOldPosts()
    ]),
    builder: (context, snap) {
     if (snap.hasError) {

        debugPrint('${snap.error}');
        return ErrorContent(snap.error);

      } else if (!snap.hasData) {

        return Center(
          child: CircularProgressIndicator(),
        );

      }

      newPosts = snap.data[0];
      oldPosts = snap.data[1];

      return _pageContent();
    }
  );
}

我从头开始写代码,所以可能会有一些小错误,但我希望你能明白我的意思,享受:)

您可以使用异步包中的 StreamGroup:https://pub.dev/documentation/async/latest/async/StreamGroup-class.html 对来自多个流的事件进行分组 - 它由 dart 团队详细记录和维护。如果你没有 RxDart 经验,这是一个不错的选择。它不具备 rx 的所有功能,但对于初学者来说,理解它应该更容易