Я работаю над приложением для чата, используя Flutter и Firebase. Я новичок в Dart и поэтому застрял, когда хотел создать функцию, которая извлекает (используя ожидание) конкретный документ из одной коллекции (форумов) и использует свойство массива документа форума для запроса и возврата потока из другой коллекции ( открытые сообщения). Проблема с моим текущим решением заключается в том, что оно всегда возвращает пустой массив. Я уверен, что неправильно использую ключевые слова или логику. Не могли бы вы помочь мне реорганизовать мой метод.
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;}
Вы можете использовать следующий метод.
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;
}
}
}
Или
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());
}
Вы также могли бы взять вывод .snapshots и использовать для него соответствующую обработку .map и вернуть его как поток напрямую. Нет необходимости в асинхронной синхронизации с асинхронной передачей туда и обратно.