简体   繁体   English

Firebase 实时数据库按键排序

[英]Firebase Realtime Database Ordering by Keys

I want to sort data in Firebase realtime database.我想对 Firebase 实时数据库中的数据进行排序。

在此处输入图像描述

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.谢谢。

Have you tried with ".orderByChild()"?你试过“.orderByChild()”吗?

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. Map中的键顺序未定义。 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.因此,当您调用(snapshot.data as DatabaseEvent).snapshot.value as Map<dynamic, dynamic>)时,实际上是在删除数据库返回的所有排序信息。

To process the results in the correct order, iterate over the children of the snapshot , and only then convert each child to a Map .要以正确的顺序处理结果,请遍历snapshotchildren ,然后才将每个子代转换为Map

Complementing Frank , try to assign snapshot to a List of snapshots using List snapshotList = xxx.children.toList();作为Frank的补充,尝试使用List snapshotList = xxx.children.toList(); If you do something like snapshotList[i].value you will notice that the key is not present, the solution to get it back is to use the get .key .如果您执行类似snapshotList[i].value的操作,您会注意到该密钥不存在,将其取回的解决方案是使用 get .key

You can see bellow an exemple how I did to solve the same problem in my project.你可以在下面看到一个例子,我是如何在我的项目中解决同样的问题的。

final List<DataSnapshot> snapshotList = snapshot.data.children.toList();

final List<Map> commentsList = [];

for (var i in snapshotList) {
  Map<String?, Map> comment = {i.key: i.value as Map};
  commentsList.add(comment);
}

In the code above, commentsList will get you a list of Maps ordered according to original database.在上面的代码中,commentsList 将为您提供根据原始数据库排序的地图列表。

I hope this help.我希望这会有所帮助。 If anyone has a more straightforward solution, please, share with us.如果有人有更直接的解决方案,请与我们分享。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM