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:
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With