'Flutter: Get Data from Firebase using Future wait
I'm trying to load real-time data for a chat using BLoC but I'm stumped on how to get this to work right & retrieve data.
The goal is to build this using BLoC so I can load in messages right away, handle pagination to bring in more messages, and reload if a message is deleted, flagged, etc.
I'm always hitting my empty state. The return is called right away but the await does run and I can log out that I am getting all my messages. I just don't know how to return once all of that is complete so I can display them for a user.
Here is what I have tried:
Future _loadChatMessages(
DatabaseReference ref, int numberOfMessages) async {
// Number of chats...
numberOfChatsToDisplay = numberOfChatsToDisplay + numberOfMessages;
// clear our messages...
chatMessages.clear();
// get our messages...
ref.orderByKey().limitToLast(numberOfChatsToDisplay).onValue.listen(
(event) async {
final firebaseData = Map<String, dynamic>.from(event.snapshot.value);
await Future.wait(
firebaseData.values.map(
(message) async {
var shouldAdd = true;
final mappedMessage = Map<String, dynamic>.from(message);
// check if message was flagged
shouldAdd = false;
// check if user was blocked
shouldAdd = false;
// create new message
final newMessage = Message.fromJson(mappedMessage);
if (shouldAdd) {
chatMessages.add(newMessage);
}
},
),
);
},
);
// This just gets called right away and is empty, never called again
return chatMessages;
}
Solution 1:[1]
The onValue property is a stream, which immediately fires an event with the current data from the database, and then again whenever there's a change to the database. Since there may be multiple events, you can meaningfully use await when listening to a stream.
If you do want the stream, there's simply no way to (meaningfully)nreturn a single value.
If you only want one value, use once instead of onValue:
Future _loadChatMessages(DatabaseReference ref, int numberOfMessages) async {
numberOfChatsToDisplay = numberOfChatsToDisplay + numberOfMessages;
chatMessages.clear();
var snapshot = await ref.orderByKey().limitToLast(numberOfChatsToDisplay).once();
final firebaseData = Map<String, dynamic>.from(snapshot.value);
firebaseData.values.map((message) {
var shouldAdd = true;
final mappedMessage = Map<String, dynamic>.from(message);
shouldAdd = false;
shouldAdd = false;
final newMessage = Message.fromJson(mappedMessage);
if (shouldAdd) {
chatMessages.add(newMessage);
}
});
return chatMessages;
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Frank van Puffelen |
