I have a chat app in Flutter using Firestore, and I have two main collections:
chats, which is keyed on auto-ids, and has message,
You can do it with RxDart like that.. https://pub.dev/packages/rxdart
import 'package:rxdart/rxdart.dart';
class Messages {
final String messages;
final DateTime timestamp;
final String uid;
final DocumentReference reference;
Messages.fromMap(Map map, {this.reference})
: messages = map['messages'],
timestamp = (map['timestamp'] as Timestamp)?.toDate(),
uid = map['uid'];
Messages.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.reference);
@override
String toString() {
return 'Messages{messages: $messages, timestamp: $timestamp, uid: $uid, reference: $reference}';
}
}
class Users {
final String name;
final DocumentReference reference;
Users.fromMap(Map map, {this.reference})
: name = map['name'];
Users.fromSnapshot(DocumentSnapshot snapshot)
: this.fromMap(snapshot.data, reference: snapshot.reference);
@override
String toString() {
return 'Users{name: $name, reference: $reference}';
}
}
class CombineStream {
final Messages messages;
final Users users;
CombineStream(this.messages, this.users);
}
Stream> _combineStream;
@override
void initState() {
super.initState();
_combineStream = Observable(Firestore.instance
.collection('chat')
.orderBy("timestamp", descending: true)
.snapshots())
.map((convert) {
return convert.documents.map((f) {
Stream messages = Observable.just(f)
.map((document) => Messages.fromSnapshot(document));
Stream user = Firestore.instance
.collection("users")
.document(f.data['uid'])
.snapshots()
.map((document) => Users.fromSnapshot(document));
return Observable.combineLatest2(
messages, user, (messages, user) => CombineStream(messages, user));
});
}).switchMap((observables) {
return observables.length > 0
? Observable.combineLatestList(observables)
: Observable.just([]);
})
}
for rxdart 0.23.x
@override
void initState() {
super.initState();
_combineStream = Firestore.instance
.collection('chat')
.orderBy("timestamp", descending: true)
.snapshots()
.map((convert) {
return convert.documents.map((f) {
Stream messages = Stream.value(f)
.map((document) => Messages.fromSnapshot(document));
Stream user = Firestore.instance
.collection("users")
.document(f.data['uid'])
.snapshots()
.map((document) => Users.fromSnapshot(document));
return Rx.combineLatest2(
messages, user, (messages, user) => CombineStream(messages, user));
});
}).switchMap((observables) {
return observables.length > 0
? Rx.combineLatestList(observables)
: Stream.value([]);
})
}