I am trying to make 2 queries to Firestore and merge the results into one in order to simulate a Firestore OR query.
I got back the Firestore todos example and particularly the FirebaseTodosRepository class.
class FirebaseTodosRepository implements TodosRepository {
final todoCollection = Firestore.instance.collection('todos');
// ….
@override
Stream<List<Todo>> todos() {
return todoCollection.where("owners", arrayContains: userId).snapshots().map((snapshot) {
return snapshot.documents.map((doc) => Todo.fromEntity(TodoEntity.fromSnapshot(doc)))
.toList();
});
}
I would like to merge the result of 2 queries but I don't know how to proceed despite some unsuccessful researchs.
todoCollection.where("owners", arrayContains: userId).snapshots().map((snapshot) {
return snapshot.documents.map((doc) => Todo.fromEntity(TodoEntity.fromSnapshot(doc)))
.toList();
});
todoCollection.where("contributors", arrayContains: userId).snapshots().map((snapshot) {
return snapshot.documents.map((doc) => Todo.fromEntity(TodoEntity.fromSnapshot(doc)))
.toList();
});
Thanks again for your time.
if you are using rxdart, you can replace Stream<List<Todo>> todos() function with a function of type
ReplaySubject<Todo>
it will give you all the Todos that were passed
Hi @FTholin 👋
Thanks for opening an issue!
You should be able to do something like:
Future<Stream> combineStreams() async {
Stream stream1 = todoCollection
.where("owners", arrayContains: userId)
.snapshots()
.map((snapshot) {
return snapshot.documents
.map((doc) => Todo.fromEntity(TodoEntity.fromSnapshot(doc)))
.toList();
});
Stream stream2 = todoCollection
.where("contributors", arrayContains: userId)
.snapshots()
.map((snapshot) {
return snapshot.documents
.map((doc) => Todo.fromEntity(TodoEntity.fromSnapshot(doc)))
.toList();
});
return StreamZip(([stream1, stream2])).asBroadcastStream();
}
Hope that helps! 👍
Also for future reference please try to avoid posted non-bloc-related questions here, thanks!
I post my solution for those who need to working deeper on FirestoreTodos example.
///private method to zip QuerySnapshot streams
Stream<List<QuerySnapshot>> _combineStreams(String userId) {
var stream1 = todosCollection
.where("owners", arrayContains: userId)
.snapshots();
var stream2 = todosCollection
.where("contributors", arrayContains: userId)
.snapshots();
return StreamZip(([stream1, stream2])).asBroadcastStream();
}
///exposed method to be consumed by repository
Stream<List<Todo>> todos(String userId) {
var controller = StreamController<List<Todo>>();
_combineStreams(userId).listen((snapshots) {
List<DocumentSnapshot> documents = List<DocumentSnapshot>();
snapshots.forEach((snapshot) {
documents.addAll(snapshot.documents);
});
final todos = documents.map((doc) {
return Todo.fromEntity(TodoEntity.fromSnapshot(doc));
}).toList();
controller.add(todos);
});
return controller.stream;
}
Thanks again for your time guys.
Most helpful comment
I post my solution for those who need to working deeper on FirestoreTodos example.
Thanks again for your time guys.