Firestore pagination last visible document throws out of bound exception

10

Have tried to use Firestore pagination by using these links https://stackoverflow.com/a/50742175/4232013 but i facing a ArrayIndexOutOfBoundsException suddenly after some added documents in collection can any one help me to point out where i am making a mistake thanks. My code:

 private int limit = 2;
private int PostLimit = 1;

   private void GettingFollowingList() {
    followingList = new ArrayList<>();
    String UserID = FirebaseAuth.getInstance().getUid();
    followingList.add(UserID);

    FirebaseFirestore db = FirebaseFirestore.getInstance();
    db.collection("Users")
            .document(UserID)
            .collection("UserDetails")
            .document(UserID)
            .collection("Following")
            .get()
            .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                @Override
                public void onComplete(@NonNull Task<QuerySnapshot> task) {
                    if (task.isSuccessful()) {
                        for (QueryDocumentSnapshot documentSnapshot : task.getResult()) {
                            Followers followers = documentSnapshot.toObject(Followers.class);
                            followingList.add(followers.getFollow_id());
                            Log.d(TAG, "onComplete: FolloIDS: " + followers.getFollow_id());
                        }

                        ReadingPosts();
   

                    } else {
                        Log.d(TAG, "Error getting documents: ", task.getException());
                    }
                }
            });

}

My Paging :

     private void ReadingPosts() {


    String userId = FirebaseAuth.getInstance().getUid();
    FirebaseFirestore db = FirebaseFirestore.getInstance();

    followingList.add(userId);
    final CollectionReference UserRef = db.collection("UserPosts");
    Query query = UserRef.limit(limit);

    query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull final Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                for (QueryDocumentSnapshot documentSnapshot : task.getResult()) {
                    
                    for (String id : followingList) {
                       

                        if (documentSnapshot.getId().equals(id)) {
                            Log.d(TAG, "onComplete: IDS3 :" + id);
                            FirebaseFirestore db = FirebaseFirestore.getInstance();
                            CollectionReference PostRef = db.collection("UserPosts")
                                    .document(id)
                                    .collection("Posts");

                            Query query = PostRef.orderBy("timestamp", Query.Direction.DESCENDING).limit(PostLimit);

                            query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                                @Override
                                public void onComplete(@NonNull Task<QuerySnapshot> task) {

                                    if (task.isSuccessful()) {
                                        for (QueryDocumentSnapshot documentSnapshot1 : task.getResult()) {
                                            Posts posts = documentSnapshot1.toObject(Posts.class);
                                            postsList.add(posts);
                                            
                                        }
                                    }

                                    postsAdapter.notifyDataSetChanged();
                                    swipeRefreshLayout.setRefreshing(false);
                                }
                            })

                                    .addOnFailureListener(new OnFailureListener() {
                                        @Override
                                        public void onFailure(@NonNull Exception e) {
                                            Log.d(TAG, "onFailure: Failed to get the posts");
                                        }
                                    });
                        }
                    }

                    postsAdapter.notifyDataSetChanged();
                }

                lastVisible = task.getResult().getDocuments().get(task.getResult().size() - 1);

                RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {

                    @Override
                    public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                        super.onScrollStateChanged(recyclerView, newState);
                        if (newState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
                            isScrolling = true;
                        }
                    }

                    @Override
                    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                        super.onScrolled(recyclerView, dx, dy);
                        LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
                        int firstVisibleItemPosition = linearLayoutManager.findFirstVisibleItemPosition();
                        int VisibleItemCount = linearLayoutManager.getChildCount();
                        int TotalItemCount = linearLayoutManager.getItemCount();

                        if (isScrolling && (firstVisibleItemPosition + VisibleItemCount == TotalItemCount) && !isLastItemReached) {
                            isScrolling = false;
                            Query nextQuery = UserRef.startAfter(lastVisible).limit(2);
                            nextQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                                @Override
                                public void onComplete(@NonNull Task<QuerySnapshot> task1) {
                                    if (task1.isSuccessful()) {
                                        for (QueryDocumentSnapshot documentSnapshot : task1.getResult()) {
                                           
                                            for (String id : followingList) {
                                                
                                                if (documentSnapshot.getId().equals(id)) {
                                                    Log.d(TAG, "onComplete: IDS3 :" + id);
                                                    FirebaseFirestore db = FirebaseFirestore.getInstance();
                                                    CollectionReference PostRef = db.collection("UserPosts")
                                                            .document(id)
                                                            .collection("Posts");

                                                    Query query = PostRef.orderBy("timestamp", Query.Direction.DESCENDING).limit(PostLimit);

                                                    query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                                                        @Override
                                                        public void onComplete(@NonNull Task<QuerySnapshot> task) {

                                                            if (task.isSuccessful()) {
                                                                for (QueryDocumentSnapshot documentSnapshot1 : task.getResult()) {
                                                                    Posts posts = documentSnapshot1.toObject(Posts.class);
                                                                    postsList.add(posts);
                                                                }
                                                            }

                                                            postsAdapter.notifyDataSetChanged();
                                                        }
                                                    })

                                                            .addOnFailureListener(new OnFailureListener() {
                                                                @Override
                                                                public void onFailure(@NonNull Exception e) {
                                                                    Log.d(TAG, "onFailure: Failed to get the posts");
                                                                }
                                                            });
                                                }
                                            }


                                        }

                                        postsAdapter.notifyDataSetChanged();
                                        lastVisible = task1.getResult().getDocuments().get(task1.getResult().size() - 1);

                                        if (task1.getResult().size() < limit) {
                                            isLastItemReached = true;
                                        }
                                    }
                                }
                            });
                        }

                    }
                };
                post_recycler_view.addOnScrollListener(onScrollListener);


            } else {
                Log.d(TAG, "Error getting documents: ", task.getException());
            }
        }
    });

}

I am facing a error output on this line

  lastVisible = task1.getResult().getDocuments().get(task1.getResult().size() - 1);

My log output

java.lang.ArrayIndexOutOfBoundsException: length=0; index=-1 at java.util.ArrayList.get(ArrayList.java:439)

answered question

1 Answer

2

The error message is telling you that the page of results that you got contained 0 documents. If task1.getResult().size() returns 0, then subtracting 1 from that would be -1, and you can't index into an array with -1. You should check the size before you do anything with it.

posted this

Have an answer?

JD

Please login first before posting an answer.