Correctly sort nodes from newest to oldest

I am using a FirebaseRecyclerAdapter to inflate a RecyclerView with data provided by the Firebase Realtime Database.

I began sorting the nodes by their child date which was set to be the value of ServerValue.TIMESTAMP . I added a indexOn property to the parent node of the nodes I want to sort with the value date to the Firebase Database Rules.

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

This worked fine but newer nodes were added to the end of my RecyclerView . As the FirebaseRecyclerAdapter and its FirebaseArray add nodes with a ChildEventListener , it means that the data was sorted from oldest to newest .

I managed to reverse this by using the negative value of 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());
        }
    });
}

Now the nodes I want to sort look like this.

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

They are sorted from newest to oldest and get added to the top of my RecyclerView exactly as I wanted it to be.

Coming to my personal question:

  • Is this a proper way to sort nodes from newest to oldest? This seems like a big workaround to me.
  • Am I missing something?
  • Thanks in advance!

    Edit: I just saw that my prepareUpload() method is uselessly sending the negative value to the database again, just to receive it once again afterwards.. I will change this to calculate the negative value on client side. Please ignore this.


    No, you are not missing anything. And yes, that's a proper way to sort nodes from newest to oldest.

    That's just the way firebase works. Many times, you might feel like you're doing a big workaround and you think "There must be a simpler way to do this", but there's probably not.

    Firebase is indeed a great platform to build your application on. But it still has a few things to improve, like the realtime database. I mean, there is no way to query your data properly. You may be able to do some basic filtering and sorting, but If you want to do more than that, you're on your own.

    To help us with that, they have created the Firebase Database for SQL Developers Series which you can watch on this link. Those series explain that there is no proper/default way to structure your data on Firebase. Everytime you start a different project, you'll always have to spend some minutes brainstorming about how you can structure the data in a way that it simplifies and reduces queries for better performance.

    I hope Google some day implements more searching and filtering capabilities in this data service.


    In terms of getting the sort order that you want, yes, inverted time stamps are the answer. Check out this older answer: https://stackoverflow.com/a/25613337/4816918 for more information.

    The .indexOn key is only for performance optimizations (see the bottom of the "Index Your Data" page, so the correct way to request ordered data is by using .orderByChild , .orderByKey , or .orderByValue in your query. Look for the "Sort data" section of the "Work with Lists of Data on Android" page.


    What you have done is absolutely correct. The only difference is, you should have both, a timestamp and a negativeTimestamp key just in case you need either of them. It all depends on your requirements anyways.

    In-fact people from firebase suggest the same. You can watch this youtube video and move to 04:40 to see the answer to your question from the firebase team themselves.

    链接地址: http://www.djcxy.com/p/37928.html

    上一篇: Matlab sin(pi)及其与机器epsilon的关系

    下一篇: 正确排序从最新到最旧的节点