I am storing data in Firebase storage.
Object Comment
with attribute timestamp
. When I push data from device to Firebase I\'m populating
I found the current firebase version supports descending order sorting:
citiesRef.orderBy("name", "desc").limit(3)
https://firebase.google.com/docs/firestore/query-data/order-limit-data
Hope it helps
Firebase can order the items in ascending order by a given property and then returns either the first N items (limitToFirst()
) or the last N items (limitToLast()
). There is no way to indicate that you want the items in descending order.
There are two options to get the behavior you want:
Use a Firebase query to get the correct data, then re-order it client-side
Add a field that has a descending value to the data
For the latter approach, it is common to have a inverted timestamp.
-1 * new Date().getTime();
Swift 3:
let query = firebase.child(YourQueryPath).queryOrdered(byChild: YourQueryChild).queryLimited(toLast: YourLimit)
query.observeSingleEvent(of: .value, with: { (snapshot) in
// Reverse order here to get top **YourLimit** results in descending order
})
I don't see any option to reverse the data. But One Brute way is to get the data.
List<ModelClass> mList=new ArrayList();
public void onDataChange(DataSnapshot dataSnapshot)
{
mList.clear();
for(DataSnapshot children: dataSnapshot.getChildren()){
ModelClass modelClass=children.getValue(ModelClass.class);
mList.add(modelClass);
}
Collections.reverse(mList);
Adapter.notifyDataSetChanged();
}
Based on Himanshus answer but Im using kotlin and instead of the timestamp in the question Im ordering by score which should be similar. I'm not sure if firebase has an ascending or descending function but this is what ended working for me in my current project. I hope it will help someone else in the near future.
FirebaseFirestore.getInstance().collection("leaderboard")
.orderBy("score")
.addSnapshotListener { snapshot, exception ->
if (exception != null) {
Log.e("Exception:", "Could not retrieve scores ${exception.localizedMessage}")
}
if (snapshot != null) {
scores.clear()
for (document in snapshot.documents) {
val data = document.data
val name = data?.get("name") as? String
val score = data?.get("score") as? Number
val documentId = document.id
val newScore = Score(name, score, documentId)
scores.add(newScore)
}
scores.reverse()
scoresAdapter.notifyDataSetChanged()
}
}
This is what worked for me. Happy coding!
The @Monet_z_Polski approach, based on
@Override
public T getItem(int position) {
return super.getItem(getCount() - (position + 1));
}
does have a weird effect on not update FirebaseRecyclerView automatically (PopulateViewHolder is not triggered in realtime changes). So, the best option is use a negative key to index the data.