如何合并多个Firestore查询

时间:2019-11-16 17:53:08

标签: firebase flutter dart google-cloud-firestore

如何组合多个关于streambuilder的查询,我只能访问最后一个查询,以及如何防止每次返回页面时刷新刷新流

Stream<dynamic> _main;

@override
  void initState() {
    super.initState();
    _m = _firestore
        .collection(..)
        .where(..)
        .where(..)
        .snapshots()
        .listen((QuerySnapshot snapshot) => _onMUpdate(snapshot));
  }

void _onMUpdate(QuerySnapshot snapshot) async {
    snapshot.documents.forEach((doc) {
        Stream<DocumentSnapshot> u = _firestore
            .collection(..)
            .document(doc.data['m'])
            .snapshots();
        Stream<QuerySnapshot> me = _firestore
            .collection(..)
            .document(doc.documentID)
            .collection(..)
            .limit(1)
            .snapshots();
        Stream<QuerySnapshot> n = _firestore
            .collection(..)
            .document(doc.documentID)
            .collection(..)
            .snapshots();
        _main =  StreamZip([u, me, n]).asBroadcastStream();
    });
  }

在此先感谢您的帮助

2 个答案:

答案 0 :(得分:1)

在您的情况下,我认为最好使用Observable。

  1. 您可以创建单独的BLoC类。
  2. 将所有流放在那里
  3. 在此处创建吸气剂
Observable<String> get merge => Observable.zip3(
  _stream1,
  _stream2,
  _stream3,
  (one, two, three) =>
      (one.toString() + two.toString() + three.toString()));

然后,您可以像这样在Streambuilder中使用此吸气剂

StreamBuilder<String>(
            stream: counterBloc.merge,
            builder: (context, snapshot) {
              return Text(
                'Flutter Observable - ${snapshot.data.toString()}',
              );
            }),

我在柜台应用程序的基础上创建了示例。按下按钮时,它将数据发送到3个流,并在显示它们之后。

代码示例在这里https://github.com/awaik/flutter_observable_example

它的工作原理类似于下图。

https://pub.dev/documentation/rxdart/latest/rx/Observable/zip3.html

上了解有关zip3的更多信息

也可以使用Stream<DocumentSnapshot>代替BehaviorSubject<DocumentSnapshot>,它将保留流的最后一个值。

通过这种方法,您可以将逻辑与UI分开,并可以在应用程序中的任何位置重用此流。

enter image description here

答案 1 :(得分:0)

StreamBuilder将基于上一个快照更新布局,因此,如果您将其组合在一起,则没有关系,只有最后一个会更新屏幕。

我相信您可以在StreamBuilder上执行以下操作:

// snapshotList will be your AsyncSnapshot. snapshotList.data will be your List<QuerySnapshot>

StreamBuilder<List<QuerySnapshot>>(
    stream: streamList,
    builder: (BuildContext context, AsyncSnapshot<List<QuerySnapshot>> snapshotList) {
        snapshotList.data.forEach((doc) {
            return something
        }
    }
)

让我知道这是否对您有用:)