How to get last visible DocumentSnapshot in a combined task for Firestore queries?

Sabeeh Ul Haq :

I am combining two queries to do the "not equals" query for a Firestore collection which isn't possible natively in Firestore so I have to do it locally. I need to get the last visible document of my combined task to use for pagination.

Following is the code that I am writing to get a list of documents from both query results.

    Query first = firebaseFirestore
            .collection("jobs")
            .whereGreaterThan("createdBy",currentUser.getEmail())
            .orderBy("createdDate",Query.Direction.ASCENDING)
            .limit(2);
    Query second = firebaseFirestore
            .collection("jobs")
            .whereLessThan("createdBy",currentUser.getEmail())
            .orderBy("createdDate",Query.Direction.ASCENDING)
            .limit(2);

    Task<QuerySnapshot> firstTask = first.get();
    Task<QuerySnapshot> secondTask = second.get();


    final Task<List<QuerySnapshot>> combinedTask = Tasks.whenAllSuccess(firstTask, secondTask);
    combinedTask.addOnSuccessListener(new OnSuccessListener<List<QuerySnapshot>>() {
        @Override
        public void onSuccess(List<QuerySnapshot> querySnapshots) {
            List<Job> list = new ArrayList<>();
            for(QuerySnapshot qs: querySnapshots){
                for(DocumentSnapshot document: qs){
                    Job job = document.toObject(Job.class);
                    list.add(job);
                }
            }

            JobAdapter jobAdapter = new JobAdapter(list);
            recyclerView.setAdapter(jobAdapter);

            DocumentSnapshot lastVisible = combinedTask.getResult().get()

        }
    });

In the line

 DocumentSnapshot lastVisible = combinedTask.getResult().get()

I can only either access the documents from my first query or my second query so I am unsure how to get the last visible document, I think the last document would be from my second query logically but I am unsure.

Here is the tutorial I was following to accomplish this:

https://www.youtube.com/watch?v=KdgKvLll07s

Alex Mamo :

You can solve this, by simply creating the lastVisible as a global variable in your class:

private DocumentSnapshot lastVisible;

And then assignin a value in the for loop:

final Task<List<QuerySnapshot>> combinedTask = Tasks.whenAllSuccess(firstTask, secondTask);
combinedTask.addOnSuccessListener(new OnSuccessListener<List<QuerySnapshot>>() {
    @Override
    public void onSuccess(List<QuerySnapshot> querySnapshots) {
        List<Job> list = new ArrayList<>();
        for(QuerySnapshot qs: querySnapshots){
            for(DocumentSnapshot document : qs){
                Job job = document.toObject(Job.class);
                list.add(job);
                lastVisible = qs.getDocuments().get(qs.size() - 1);
            }
        }
        Query nextQuery = firebaseFirestore
                .collection("jobs")
                .whereGreaterThan("createdBy",firebaseAuth.getCurrentUser().getEmail())
                .orderBy("createdDate",Query.Direction.ASCENDING)
                .startAfter(lastVisible)
                .limit(2);

        //Use the nextQuery
    }
});

See the call to .startAfter(lastVisible)? So this will work because at the end of the for loop, the lastVisible object will always hold the value of the last DocumentSnapshot object.

P.S. Thanks for using my tutorial as an example for your Firestore pagination :)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=356161&siteId=1