Ffltter Firebase合并Streams列表和CombineLatestStream并在StreamBuilder上显示

人气:242 发布:2022-10-16 标签: firebase flutter google-cloud-firestore

问题描述

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

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?>>?
我的问题很清楚,但简单地说,我有一个名为comineList的流列表,该列表中的流的数量完全取决于用户,因此流的数量因用户而异,我需要组合这个comineList并在StreamBuilder中将其打印为单个流。目前我找到的最好的方法是CombineLatestStream方法,但我在StreamBuilder中调用它时遇到了我提到的错误。

我已经处理这件事好几天了。有一次我得到一个错误,WHERE查询被限制为只有10个值。当我了解到这一点时,我了解到我必须分别查询流,然后将它们合并。我分别查询流,使用StreamGroup.Merge和Rx.Merge方法合并它们,然后将它们与StreamGroup.Merge和Rx.Merge方法合并。我弄错了。收到错误后,我了解到需要将流与comineLatest方法合并,现在我收到此错误。

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

推荐答案

经过一番努力,我终于解决了问题。我给那些有同样问题的人的答案。

首先,我意识到我错误地组合了名为comineList的流列表,所以我更改了合并方法,如下所示:

var totalRef = CombineLatestStream.list(combineList);

然后我更改了StreamBuilder设计:

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

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

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

List<QuerySnapshot> querySnapshot =
                                snapshotList.data;

                            List<DocumentSnapshot> listOfDocumentSnapshot = [];

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

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

然后我可以在ListView.Builder中按索引号调用每个数据。

488