I want to sort data in Firebase realtime database.
I am using timestamp as key when saving data and I want to sort data by timestamps. I used below code for this purpose.
Widget buildList(ChatUser chatUser) {
return Flexible(
child: StreamBuilder(
stream: _service
.getMessages(chatUser.uid!)
.orderByKey()
.onValue,
builder: (context, snapshot) {
List<ChatMessage> messageList = [];
if (snapshot.hasData) {
final myMessages = Map<dynamic, dynamic>.from(
(snapshot.data as DatabaseEvent).snapshot.value
as Map<dynamic, dynamic>);
myMessages.forEach((key, value) {
final currentMessage = Map<String, dynamic>.from(value);
final message = ChatMessage().fromJson(currentMessage);
messageList.add(message);
});
if (messageList.isNotEmpty) {
return ListView.builder(
padding: const EdgeInsets.all(10),
reverse: true,
itemCount: messageList.length,
controller: scrollController,
itemBuilder: (context, index) {
return buildItem(index, messageList[index], chatUser);
});
} else {
return const Center(
child: Text('Henüz Mesaj yok.'),
);
}
} else {
return const Center(
child: CircularProgressIndicator(
color: Colors.red,
),
);
}
}));
}
As a result, data does not come according to key values, it comes in different orders.
Any suggestions ? Thanks.
2
Answers
The problem is in how you process the results here:
The order of the keys inside a
Map
is by definition undefined. So when you call(snapshot.data as DatabaseEvent).snapshot.value as Map<dynamic, dynamic>)
, you’re actually dropping all ordering information that the database returns.To process the results in the correct order, iterate over the
children
of thesnapshot
, and only then convert each child to aMap
.Complementing Frank, try to assign snapshot to a List of snapshots using
List snapshotList = xxx.children.toList();
If you do something likesnapshotList[i].value
you will notice that the key is not present, the solution to get it back is to use the get.key
.You can see bellow an exemple how I did to solve the same problem in my project.
In the code above, commentsList will get you a list of Maps ordered according to original database.
I hope this help. If anyone has a more straightforward solution, please, share with us.