【问题标题】:How to merge two streams and emit them simultaneously using StreamBuilder如何使用 StreamBuilder 合并两个流并同时发出它们
【发布时间】:2021-02-20 12:40:42
【问题描述】:

我正在尝试同时向 Firebase 发出 2 个查询,然后将它们的结果作为单个流进行流式传输,并在它们通过时一次发出一个结果。

我已经尝试使用下面的代码,但似乎只有一个流可以工作,即使两个流都应该有结果。

Stream<QuerySnapshot> searchQuery(String searchQuery) {
    final firstStream = FirebaseFirestore.instance
        .collectionGroup("newProduct")
        .where('sWords', arrayContains: searchQuery)
        .snapshots();

    final secondStream = FirebaseFirestore.instance
        .collectionGroup("usedProduct")
        .where("sWords", arrayContains: searchQuery)
        .snapshots();

    final mergedStream = Rx.merge([firstStream, secondStream]);

    return mergedStream;
  }

这是我使用合并流的 StreamBuilder

StreamBuilder(
          stream: _marketDatabaseService.searchQuery(_searchQuery),
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return Text("An error has occurred!");
            } else if (snapshot.hasData &&
                snapshot.connectionState == ConnectionState.active) {
              List<QueryDocumentSnapshot> querySnapshot =
                  snapshot.data.documents;

              return ListView.builder(
                  itemCount: querySnapshot.length,
                  itemBuilder: (BuildContext context, int index) {
                      return Text(querySnapshot[index]["prN"]);
                  });
            } else {
              return Center(
                child: CircularProgressIndicator(
                  backgroundColor: Colors.blue,
                ),
              );
            }
          },
        ),

注意:我在这个例子中使用了 rxdart 包。

【问题讨论】:

  • 您可能想使用来自package:asyncStreamGroup
  • 我实际上已经使用 StreamZip 解决了这个问题。你能给我一个例子,说明如何使用 StreamGroup 来实现我想要的结果。

标签: flutter dart


【解决方案1】:

要在 Firebase 中查询 2 个集合,请使用以下代码 sn-p:

Stream<List<QuerySnapshot>> getData(String searchQuery) {
    Stream stream1 = FirebaseFirestore.instance
        .collectionGroup('newProdut')
        .where('sWords', arrayContains: searchQuery)
        .snapshots();
    Stream stream2 = FirebaseFirestore.instance
        .collectionGroup('usedProduct')
        .where('sWords', arrayContains: searchQuery)
        .snapshots();
    return StreamZip([stream1, stream2]);
  }

然后在您的 StreamBuilder Widget 中使用以下代码 sn-p 来输出数据:

     StreamBuilder(
            stream: getData(_searchQuery),
            builder: (context, snapshot) {
              if (snapshot.hasError) {
                return Text("An error has occurred!");
              } else if (snapshot.hasData &&
                  snapshot.connectionState == ConnectionState.active) {

                List<QuerySnapshot> querySnapshot = snapshot.data.toList();

                List<QueryDocumentSnapshot> documentSnapshot = [];

                querySnapshot.forEach((query) {
                   documentSnapshot.addAll(query.docs);
                });

                /// This "mappedData" will contain contents from both streams
                List<Map<String, dynamic>> mappedData = [];

                for (QueryDocumentSnapshot doc in documentSnapshot) {
                    mappedData.add(doc.data());
                }

                return ListView.builder(
                    itemCount: mappedData.length,
                    itemBuilder: (context, index) {
                      return Text(mappedData[index]["prN"]);
                    });
              } else {
                return Center(
                  child: CircularProgressIndicator(
                    backgroundColor: Colors.blue,
                  ),
                );
              }
            },
          ),

【讨论】:

    猜你喜欢
    • 2015-01-08
    • 2020-11-07
    • 2021-03-26
    • 2023-03-26
    • 1970-01-01
    • 2020-05-01
    • 2017-11-22
    • 2021-02-19
    • 1970-01-01
    相关资源
    最近更新 更多