I am working on a chat app using Flutter and Firebase. I am new to Dart and so got stuck when I wanted to create a function which fetches (using await) a particular document from one collection (forums) and use an array property of the forum document to query and return a Stream from another collection (openMessages). The problem with my current solution is that it always returns an empty array. I am sure I am using the keywords or logic incorrectly. Can you please help me refactor my method.
Stream<List<ChatMessage>> getForumChatStream(String forumId) async* {
List<ChatMessage> messages = [];
var docSnap = await firestore.collection('forums').doc(forumId).get();
Forum forum = Forum.fromMap(docSnap.data()!);
firestore
.collection('openMessages')
.where('messageId', whereIn: forum.messageIds)
.orderBy('timeSent', descending: true)
.snapshots()
.map((event) {
for (var document in event.docs) {
messages.add(ChatMessage.fromMap(document.data()));
}
});
//print('LENGTH:'+messages.length.toString());
yield messages;}
You can use the following method.
Stream<List<ChatMessage>> getForumChatStream(String forumId) async* {
final firestore = FirebaseFirestore.instance;
List<ChatMessage> messages = [];
var docSnap = await firestore.collection('forums').doc(forumId).get();
Forum forum = Forum.fromMap(docSnap.data()!);
final result = firestore
.collection('openMessages')
.where('messageId', whereIn: forum.messageIds)
.orderBy('timeSent', descending: true)
.snapshots();
await for (final r in result) {
final docs = r.docs;
for (final document in docs) {
messages.add(ChatMessage.fromMap(document.data()));
yield messages;
}
}
}
Or
Stream<List<ChatMessage>> getForumChatStream(String forumId) async* {
final firestore = FirebaseFirestore.instance;
List<ChatMessage> messages = [];
var docSnap = await firestore.collection('forums').doc(forumId).get();
Forum forum = Forum.fromMap(docSnap.data()!);
yield* firestore
.collection('openMessages')
.where('messageId', whereIn: forum.messageIds)
.orderBy('timeSend', descending: true)
.snapshots()
.map((event) =>
event.docs.map((e) => ChatMessage.fromMap(e.data())).toList());
}