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.
CodePudding user response:
Have you tried with ".orderByChild()"?
CodePudding user response:
The problem is in how you process the results here:
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);
});
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 the snapshot
, and only then convert each child to a Map
.