Home > Software engineering >  Firebase Realtime Database Ordering by Keys
Firebase Realtime Database Ordering by Keys

Time:09-11

I want to sort data in Firebase realtime database.

enter image description here

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.

result

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.

  • Related