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

Posted

技术标签:

【中文标题】从最新到最旧正确排序节点【英文标题】:Correctly sort nodes from newest to oldest 【发布时间】:2017-05-26 11:11:27 【问题描述】:

我正在使用 FirebaseRecyclerAdapterRecyclerView 添加 Firebase 实时数据库提供的数据。

我开始按子节点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() 方法无用地将负值再次发送到数据库,只是为了之后再次接收它。我将更改它以计算客户端的负值。请忽略这一点。

【问题讨论】:

【参考方案1】:

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

这就是 firebase 的工作方式。很多时候,您可能会觉得自己正在做一个很大的变通方法,并且您认为“必须有一种更简单的方法来做到这一点”,但可能没有。

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

为了帮助我们解决这个问题,他们创建了 Firebase Database for SQL Developers 系列,您可以在 link 上观看。这些系列解释说,在 Firebase 上构建数据没有适当/默认的方式。每次开始一个不同的项目时,您总是需要花几分钟的时间来思考如何以一种简化和减少查询以提高性能的方式构建数据。

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

【讨论】:

【参考方案2】:

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

事实上,来自 firebase 的人们也提出了相同的建议。您可以观看 this youtube video 并移至 04:40 以查看 Firebase 团队对您问题的回答。

【讨论】:

【参考方案3】:

就获得您想要的排序顺序而言,是的,倒置时间戳就是答案。查看这个较旧的答案:https://***.com/a/25613337/4816918 了解更多信息。

.indexOn 键仅用于性能优化(请参阅"Index Your Data" page 的底部,因此请求有序数据的正确方法是在查询中使用.orderByChild.orderByKey.orderByValue。查找"Work with Lists of Data on android" page 的“排序数据”部分。

【讨论】:

以上是关于从最新到最旧正确排序节点的主要内容,如果未能解决你的问题,请参考以下文章

如何将Firebase Recycler视图从最新(列表顶部)排序到最旧[重复]

从最新到最旧对我的提要中的帖子进行排序(使用 Swift 和 Parse)

从最新到最旧的python对Mongo列表进行排序[重复]

使用 VueFire,我如何按日期降序排列我的列表(从最新到最旧)?

golang怎么对日期和时间进行排序

我将如何打印从最旧到最新的模型字段? [复制]