【问题标题】:Flutter Firebase Merge Streams List with CombineLatestStream and Display on StreamBuilderFlutter Firebase 使用 CombineLatestStream 合并流列表并在 StreamBuilder 上显示
【发布时间】:2022-01-21 05:32:33
【问题描述】:

我有一个这样的流的组合列表;

var Ref1 = _firestore
      .collectionGroup("Posts")
      .where('postID', whereIn: List1)
      .snapshots();
  var Ref2 = _firestore
      .collectionGroup("Posts")
      .where('postID', whereIn: List2)
      .snapshots();
  var Ref3 = _firestore
      .collectionGroup("Posts")
      .where('postID', whereIn: List3)
      .snapshots();
  
  List<Stream<QuerySnapshot>> combineList = [Ref1, Ref2, Ref3];

通过这种方法,我合并来自combineList 的流;

var totalRef = Rx.combineLatest(
    combineList, (list) => (list as Iterable<Iterable>).flattened);

然后我在StreamBuilder 中使用totalRef

StreamBuilder<QuerySnapshot>(
                      stream: totalRef,
                      builder:
                          (BuildContext context, AsyncSnapshot asyncsnapshot) {
                        if (asyncsnapshot.hasError) {
                          return Center(
                            child: Text("Error"),
                          );
                        } else {
                          if (asyncsnapshot.hasData) {
                            List<DocumentSnapshot> listOfDocumentSnapshot =
                                asyncsnapshot.data.docs;
                            return ListView.builder(
                              physics: ScrollPhysics(),
                              shrinkWrap: true,
                              itemCount: listOfDocumentSnapshot.length,
                              itemBuilder: (BuildContext context, int index) {
                                return Padding(
                                  padding: const EdgeInsets.symmetric(
                                      horizontal: 12.0, vertical: 12.0),
                                  child: Container(
                                    child: Column(
                                      children: <Widget>[
                                        Stack(
                                          children: <Widget>[
                                            Align(
                                              alignment: Alignment.topCenter,
                                              child: ClipRRect(
                                                borderRadius:
                                                BorderRadius.circular(24),
                                                child: GestureDetector(
                                                  onTap: () => navigateToDetail(
                                                      listOfDocumentSnapshot[
                                                      index]),
                                                  child: Image(
                                                    height: 320,
                                                    width: 320,
                                                    fit: BoxFit.cover,
                                                    image: NetworkImage(
                                                        listOfDocumentSnapshot[
                                                        index]["photo"]),
                                                  ),
                                                ),
                                              ),
                                            ),
                                          ],
                                        ),
                                      ],
                                    ),
                                  ),
                                );
                              },
                            );
                          }
                           else {
                            return Center(
                              child: CircularProgressIndicator(
                                color: Colors.orangeAccent[400],
                              ),
                            );
                          }
                        }
                      },
                    ),

我还列出了 StreamBuilder 中的快照数据;

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

                            List<DocumentSnapshot> listOfDocumentSnapshot = [];

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

当我在 StreamBuilder 中使用 totalRef 时,我遇到了这样的错误;

type 'CombineLatestStream<QuerySnapshot<Object>, Iterable<dynamic>>' is not a subtype of type 'Stream<QuerySnapshot<Object?>>?

我的问题很清楚,但简单总结一下,我有一个名为 combineList 的流列表,这个列表中的流数量完全取决于用户,因此流的数量因用户而异,我需要组合这个 combineList 并在 StreamBuilder 中将其打印为单个流。目前我发现的最好方法是 CombineLatestStream 方法,但是在 StreamBuilder 中调用它时出现了我提到的错误。

我已经处理这个问题好几天了。一旦我收到 whereIN 查询仅限于 10 个值的错误。当我了解到这一点时,我了解到我必须分别查询流然后合并它们。我分别查询了流,在将它们与 StreamGroup.merge 和 Rx.merge 方法结合后,我将它们与 StreamGroup.merge 和 Rx.merge 方法合并。我有错误。收到错误后,我了解到我需要将 Streams 与 combineLatest 方法合并,现在我收到此错误。

请知道答案或以前遇到过此问题的人,为我的代码编写适当的解决方案,有关代码的所有信息都已在上面,如果您希望我提供更多信息,我可以编辑问题。

【问题讨论】:

    标签: firebase flutter google-cloud-firestore


    【解决方案1】:

    经过一番努力,我解决了我的问题。对于有同样问题的人,我的回答。

    首先,我意识到我错误地合并了名为 combineList 的流列表,所以我改变了我的合并方法:

    var totalRef = CombineLatestStream.list(combineList);
    

    然后我改变了 StreamBuilder 的设计:

    StreamBuilder<List<QuerySnapshot>>(
                          stream: totalRef,
                          builder: (BuildContext context,
                              AsyncSnapshot<List<QuerySnapshot>> snapshotList) {} )
    

    因此,我将查询快照中的 StreamBuilder 转换为查询快照列表中的 StreamBuilder。

    然后,在构建器中;为了访问快照列表中的数据,我将这些快照转换为数据类型,并将其定义在 listOfDocumentSnapshot 列表中。

    List<QuerySnapshot> querySnapshot =
                                    snapshotList.data;
    
                                List<DocumentSnapshot> listOfDocumentSnapshot = [];
    
                                querySnapshot.forEach((query) {
                                  listOfDocumentSnapshot.addAll(query.docs);
                                });
    

    ListView.builder中的itemCount自然变成了这样:listOfDocumentSnapshot.length,

    然后我可以通过 ListView.builder 中的索引号调用每个数据。

    【讨论】:

      猜你喜欢
      • 2020-05-01
      • 2021-03-26
      • 2022-01-20
      • 2021-04-27
      • 2021-09-30
      • 1970-01-01
      • 2020-12-14
      • 2021-04-24
      • 2021-01-05
      相关资源
      最近更新 更多