正确排序从最新到最旧的节点

时间:2017-01-11 15:24:19

标签: android sorting firebase firebase-realtime-database

我正在使用FirebaseRecyclerAdapter使用Firebase实时数据库提供的数据来充气RecyclerView

我开始按子date对节点进行排序,该子节点设置为ServerValue.TIMESTAMP的值。我将indexOn属性添加到要使用值date排序到Firebase数据库规则的节点的父节点。

"parent-node": {
  ".read": "auth != null",
  ".write": "auth != null",
  ".indexOn" : "date",
  ...
}, 

这个工作正常但更新的节点被添加到我RecyclerView的末尾。由于FirebaseRecyclerAdapter及其FirebaseArray添加ChildEventListener节点,这意味着数据从最旧到最新排序。

我设法通过使用ServerValue.TIMESTAMP的负值来解决这个问题。

private void prepareUpload() {
    //mDatabase is a reference to the root of the Firebase Database
    final DatabaseReference timestampReference = mDatabase.child("timestamp");
    final String timestampKey = timestampReference.push().getKey();
    timestampReference.child(timestampKey).setValue(ServerValue.TIMESTAMP);
    timestampReference.child(timestampKey).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            if (dataSnapshot.getValue() != null) {
                if (!(Long.parseLong(dataSnapshot.getValue().toString()) < 0)) {
                    timestampReference.child(timestampKey).setValue(0 - Long.parseLong(dataSnapshot.getValue().toString()));
                } else {
                    upload(/*Starting upload with new timestamp here (this is just a dummy method)*/);
                    timestampReference.child(timestampKey).removeValue();
                }
            }
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            Log.e(TAG, databaseError.getMessage());
        }
    });
}

现在我要排序的节点看起来像这样。

{
  "-K_tlLWVO21NXUjUn6ko" : {
    "date" : -1483806697481,
    "debug" : "old",
    ...
  },
  "-K_tmjVqTUcKXHaQDphk" : {
    "date" : -1483807061979,
    "debug" : "newer",
    ...
  },
  "-K_uC-AJIvDOuBzhJ3JJ" : {
    "date" : -1483813945897,
    "debug" : "newest",
    ...
  }
}

它们从最新到最旧排序,并且完全按照我的要求添加到RecyclerView的顶部。

提出个人问题:

  • 这是从最新到最旧的节点排序的正确方法吗?这对我来说似乎是一个很大的解决方法。
  • 我错过了什么吗?

提前致谢!

编辑:我刚刚看到我的prepareUpload()方法无用地再次将负值发送到数据库,之后再次接收它。我将更改此值以计算客户端的负值。请忽略这一点。

3 个答案:

答案 0 :(得分:2)

不,你没有遗漏任何东西。是的,这是从最新到最旧的节点排序的正确方法。

这就是firebase的工作方式。很多时候,你可能会觉得你正在做一个大的解决方法而且你认为“必须有一个更简单的方法来做到这一点”,但可能没有。

Firebase确实是构建应用程序的绝佳平台。但它还有一些需要改进的地方,比如实时数据库。我的意思是,没有办法正确查询您的数据。您可能可以进行一些基本的过滤和排序,但如果您想要做更多的事情,那么您就可以独立完成。

为了帮助我们,他们创建了适用于SQL开发人员系列的Firebase数据库,您可以在此link上观看。这些系列解释了在Firebase上构建数据没有正确/默认的方法。每当你开始一个不同的项目时,你总是需要花一些时间来集思广益,了解如何以简化和减少查询以获得更好性能的方式构建数据。

我希望Google有朝一日能够在此数据服务中实现更多搜索和过滤功能。

答案 1 :(得分:1)

在获得所需的排序顺序方面,是的,倒置的时间戳就是答案。请查看旧答案:https://stackoverflow.com/a/25613337/4816918以获取更多信息。

.indexOn密钥仅用于性能优化(请参阅"Index Your Data" page的底部,因此请求有序数据的正确方法是使用.orderByChild.orderByKey,或在您的查询中.orderByValue。查找"Work with Lists of Data on Android" page的&#34;排序数据&#34;部分。

答案 2 :(得分:1)

你所做的是绝对正确的。唯一的区别是,您应该同时拥有timestampnegativeTimestamp密钥,以防您需要其中任何一个。这一切都取决于你的要求。

事实上,来自firebase的人们也提出了同样的看法。您可以观看this youtube video并转到04:40以查看firebase小组自己的问题答案。