Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase Firestore order by not working

I am learning about Firebase Firestore through official documentation. I was trying following code. Notifications are added using add() method of firestore.

FirebaseFirestore.getInstance().colRefNotifications()
            .orderBy("timestamp", Query.Direction.DESCENDING)
            .get()
            .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot documentSnapshots) {

            if (!documentSnapshots.isEmpty()){

                listNotifications.clear();
                recyclerViewNotification.removeAllViews();

                for (DocumentSnapshot data : documentSnapshots){

                    Notification notification = data.toObject(Notification.class);
                    listNotifications.add(notification);
                }

                notificationGeneralAdapter.notifyDataSetChanged();
            }
        }
    });

Notification.java

private String text;
private String key;
private Date timestamp;

public Notification() {
}

public Notification(String text, String key, Date timestamp) {
    this.text = text;
    this.key = key;
    this.timestamp = timestamp;
}

public String getText() {
    return text;
}

public String getKey() {
    return key;
}

public Date getTimestamp() {
    return timestamp;
}

Firestore

firestore_snapshot

I am ordering notifications by timestamp in descending direction. But, as you can see in the following snapshot, it is not showing desired output.

Snapshot

What am I doing wrong? Thank you for your help.

like image 360
Pratik ED Avatar asked Feb 05 '18 14:02

Pratik ED


2 Answers

This is happening because of nested queries. If you put a query inside a listener (success/failure/complete), orderBy method will not work. Place your next query inside onBindViewHolder of the RecyclerView adapter.

FirebaseFirestore.getInstance().colRefNotifications()
        .orderBy("timestamp", Query.Direction.DESCENDING)
        .get()
        .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
    @Override
    public void onSuccess(QuerySnapshot documentSnapshots) {

        if (!documentSnapshots.isEmpty()){
           ....

           /**If you are nesting queries like this, move second query to**/
           /**onBindViewHolder of the RecyclerView adapter**/

           FirebaseFirestore.getInstance().colRefUsers()
           .get()
           .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
           @Override
           public void onSuccess(QuerySnapshot documentSnapshots) {

               if (!documentSnapshots.isEmpty()){
               ....

               }
             }
          });
        }
    }
});
like image 82
pratiked Avatar answered Oct 03 '22 14:10

pratiked


This is happening because you are not using the timestamp as server value timestamp. You are setting the timestamp using the Date class this is not how you must do it.

Here is how you can add the timestamp using a model class. So, change your model class according with my answer from that post, also don't forget the @ServerTimestamp annotation and then your query will work fine.

like image 42
Alex Mamo Avatar answered Oct 03 '22 12:10

Alex Mamo