Flutter Firebase合并不同流列表问题



我有一个类似流的组合列表;

var Stream1 = _firestore
.collectionGroup("Infos")
.where('ID', whereIn: List1)
.snapshots();
var Stream2 = _firestore
.collectionGroup("Infos")
.where('ID', whereIn: List2)
.snapshots();
var Stream3 = _firestore
.collectionGroup("Infos")
.where('ID', whereIn: List3)
.snapshots();

List<Stream<QuerySnapshot>> combineList = [Stream1, Stream2, Stream3];

并用这种方法对combineList中的Streams进行了合并;

var totalStreams = StreamGroup.merge(combineList);

当我在StreamBuilder中使用totalStreams时,通常情况下,3个合并流的所有结果都应该显示在StreamBuilder中,但我只显示StreamBuilder中最后一个流(Streams3(的数据。

使用此包https://pub.dev/packages/async如下所示。

import 'package:async/async.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class InfosWidget extends StatefulWidget {
const InfosWidget({Key? key}) : super(key: key);
@override
State<InfosWidget> createState() => _InfosWidgetState();
}
class _InfosWidgetState extends State<InfosWidget> {
late Stream<List<List<Infos>>> _myStreamInfos;
@override
void initState() {
super.initState();
_myStreamInfos = StreamZip(
[
FirebaseFirestore.instance
.collectionGroup("Infos")
.where("id", whereIn: ["id1", "id2"])
.snapshots()
.map((query) =>
query.docs.map((map) => Infos.fromMap(map.data())).toList()),
FirebaseFirestore.instance
.collectionGroup("Infos")
.where("id", whereIn: ["id1", "id2"])
.snapshots()
.map((query) =>
query.docs.map((map) => Infos.fromMap(map.data())).toList()),
],
);
}
@override
Widget build(BuildContext context) {
return StreamBuilder<List<List<Infos>>>(
stream: _myStreamInfos,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
}
final listInfos = <Infos>[];
for (final info in snapshot.data!) {
listInfos.addAll(info);
}
return Container();
});
}
}
@immutable
class Infos {
final String id;
final String something;
const Infos({required this.id, required this.something});
Map<String, dynamic> toMap() {
return {
'id': id,
'something': something,
};
}
factory Infos.fromMap(Map<String, dynamic> map) {
return Infos(
id: map['id'] as String,
something: map['something'] as String,
);
}
}

要合并流,我可以建议您使用rxdart的CombineLatestStream。每当其中一个流发出新事件时,StreamBuilder就会构建。返回的snapshot.data是每个流的最新元素的列表。

当任何源流序列发出一个项时,组合器函数将指定的流合并为一个流序列。

在所有流至少发出一个项目之前,流不会发出。如果提供的流中有一个是空的,则生成的序列将在不发出任何项目或不使用组合器的情况下完成作用

以下是代码示例:

StreamBuilder( 
stream: CombineLatestStream.list([ 
stream0, 
stream1, 
]), 
builder: (context, snapshot) { 
final data0 = snapshot.data[0]; 
final data1 = snapshot.data[1]; 
})

另一个可能帮助您合并流的构造函数是:merge。

指定流的元素被展平为单个流序列。如果一个或多个指定流为空,则生成的序列将在不发出任何项的情况下完成。

示例代码:

static Stream<T> merge<T>(Iterable<Stream<T>> streams) =>
MergeStream<T>(streams);

这里有一个链接,显示了每个构造函数的工作原理图。

最新更新