I am having trouble by getting my messages stored in realtime db in order.
Here's my db structure
messages: {
$chatId: {
$messageId: {
timestamp: 1664884736728,
sender:"36a72WVw4weQEoXfk3T9gCtOL9n2",
message: "Hello world"
}
}
}
This is my chat repository
//get all messages of a chat
Query getMessages(String chatId) {
//get all messages of a chat
final messages = _database.ref().child("messages/$chatId");
//return all messages of a chat
return messages;
}
}
and this is how I am displaying it
StreamBuilder(
stream: _chatRepository.getMessages(chatId).onValue,
builder: (context, AsyncSnapshot snapshot) {
if (snapshot.data != null &&
snapshot.data?.snapshot?.value != null &&
snapshot.hasData) {
final messages = Map.from(snapshot.data?.snapshot.value as Map);
return ListView.builder(
itemCount: messages.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
final currChat = messages.values.toList()[index];
return BubbleCustom(...),
);
},
);
}
return Container();
},
),
This is my index in realTimeDB
{
"rules": {
"messages": {
"$chatId": {
".indexOn": ["timestamp"]
}
}
}
}
I need to get them in timestamp order. Is there any way I can do this? I hope you can help me. Thanks in advance!
CodePudding user response:
You can use orderByChild
to get the messages in the order of a specific child. So there that'd be:
stream: _chatRepository.getMessages(chatId).orderByChild('timestamp').onValue
Don't forget to define an index for timestamp
, so that the sorting can be done on the database server.
To learn more on this, see the Firebase documentation on sorting and filtering data.
CodePudding user response:
I solved it by doing it in the frontend like this:
final messages = Map.from(snapshot.data?.snapshot.value as Map);
//sort messages by timestamp ascending order
final messagesList = messages.values.toList();
messagesList.sort((a, b) => a["timestamp"].compareTo(b["timestamp"]));
final newMessagelist = List.from(messagesList.reversed);
return ListView.builder(
physics: const BouncingScrollPhysics(),
reverse: true,
itemCount: newMessagelist.length,
scrollDirection: Axis.vertical,
itemBuilder: (context, index) {
final currChat = newMessagelist[index];
return BubbleCustom(
text: currChat["message"],
isSender: currChat["sender"] == senderUser.id,
tail: true,
textStyle: TextStyle(
fontSize: 16,
color: currChat["sender"] == senderUser.id ? Colors.white : Colors.black,
),
);
},
);
with reverse: true
and inverting the list before I render it.