Search code examples
firebasekotlingoogle-cloud-firestore

Fetch collection startAfter documentID


Is there a way to fetch document after documentID like

private fun fetchCollectoionnAfterDocumentID(limit :Long){

        val db = FirebaseFirestore.getInstance()
        var query:Query = db.collection("questionCollection")
            .startAfter("cDxXGLHlP56xnAp4RmE5") //
            .orderBy("questionID", Query.Direction.DESCENDING)
        .limit(limit)

        query.get().addOnSuccessListener {
            var questions = it.toObjects(QuestionBO::class.java)
            questions.size
        }
    }

I want to fetch sorted questions after a given Document ID. I know I can do it using DocumentSnapShot. In order to fetch the second time or after the app is resume I have to save this DocumentSnapshot in Preference.

Can It be possible to fetch after document ID?

startAfter - > cDxXGLHlP56xnAp4RmE5

Edit I know I can do it using lastVisible DocumentSnapshot . But I have to save lastVisible DocumentSnapshot in sharedPreference.

When app launch first time 10 question are fetched from questionCollection. Next time 10 more question have to be fetched after those lastVisible. So for fetching next 10 I have to save DocumentSnapshot object in sharedPreference. Suggest me a better approach after seeing my database structure.

And one more thing questionID is same as Document reference ID.

enter image description here


Solution

  • There is no way you can pass only the document id to the startAfter() method and simply start from that particular id, you should pass a DocumentSnapshots object, as explained in the official documentation regarding Firestore pagination:

    Use the last document in a batch as the start of a cursor for the next batch.

    first.get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
                @Override
                public void onSuccess(QuerySnapshot documentSnapshots) {
                    =// Get the last visible document
                    DocumentSnapshot lastVisible = documentSnapshots.getDocuments()
                            .get(documentSnapshots.size() -1);
    
                    // Construct a new query starting at this document,
                    Query next = db.collection("cities")
                            .orderBy("population")
                            .startAfter(lastVisible) //Pass the DocumentSnapshot object
                            .limit(25);
    
                    // Use the query for pagination
                }
            });
    

    See, here the lastVisible is a DocumentSnapshot object which represents the last visible object. You cannot pass only a document id. For more information, you can check my answer from the following post:

    It's in Java but I'm confident you can understand it and write it in Kotlin.

    Edit:

    Please consider defining an order of your results so that all your pages of data can exist in a predictable way. So you need to either specify a startAt()/startAfter() value to indicate where in the ordering to begin receiving ordered documents or use a DocumentSnapshot to indicate the next document to receive, as explained above.

    Another solution might be to put the document id into the document itself (as a value of a property) and order on it, or you can use FieldPath.documentId() to order by the id without having to add one.

    You can also check this and this out.