3

I am using Firebase Firestore Database, I am trying to load data using dual query for pagination recyclerver data, using this Stackoverflow ans link

My code is for recycerview to load data

private void getNewFireData() {
        final int limit = 3;
        final int mmcurrentItem;
        final int totalItem;
        final int ScrolledItem;
        mRecyclerView = rootView.findViewById(R.id.rv_post_list);
        final LinearLayoutManager mManeger=new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(mManeger);
        final List<Posts> list = new ArrayList<>();
        final boolean[] isScrolling = {false};
        final boolean[] isLastItemReached = {false};
        final DocumentSnapshot lastVisible ;



        FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
        final CollectionReference postRef = rootRef.collection("posts");
        Query query = postRef.orderBy("datetime",
                Query.Direction.DESCENDING).limit(limit);
        query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {

                if(task.isSuccessful()){

                    final DocumentSnapshot[] lastVisible = {task.getResult().getDocuments().get(task.getResult().size() - 1)};

                    for (DocumentSnapshot document : task.getResult()) {
                        Posts postModel = document.toObject(Posts.class);
                        list.add(postModel);

                    }
                    final Task<QuerySnapshot>[] mSnapy = new Task[]{task};
                    final NewPostAdapter mNewPostAdapter = new NewPostAdapter(list,getActivity()
                            , mSnapy[0]);

                    mRecyclerView.setAdapter(mNewPostAdapter);


                    mRecyclerView.addOnScrollListener(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[0] =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[0] && (firstVisibleItemPosition + visibleItemCount == totalItemCount) && !isLastItemReached[0]) {
                                isScrolling[0] = false;
                                Query nextQuery = postRef.orderBy("datetime", Query.Direction.DESCENDING).startAfter(lastVisible[0]).limit(limit);
                                nextQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                                    @Override
                                    public void onComplete(@NonNull Task<QuerySnapshot> t) {
                                        if (t.isSuccessful()) {
                                            for (DocumentSnapshot d : t.getResult()) {
                                                Posts productModel = d.toObject(Posts.class);
                                                list.add(productModel);
                                                mSnapy[0] =t;

                                            }

                                            mNewPostAdapter.notifyDataSetChanged();
                                            lastVisible[0] = t.getResult().getDocuments().get(t.getResult().size() - 1);

                                            if (t.getResult().size() < limit) {
                                                isLastItemReached[0] = true;
                                            }
                                        }
                                    }
                                });
                            }

                        }
                    });


                }

            }
        });



    }

and view holder and adapter class is

public class NewPostAdapter extends RecyclerView.Adapter<NewPostAdapter.NewPostHolder> {
    private List<Posts> list;
    Context context;
    Task<QuerySnapshot> task;
    public NewPostAdapter(List<Posts> list, Context context, Task<QuerySnapshot> task) {
        this.list = list;
        this.context=context;
        this.task=task;
    }
@NonNull
@Override
public NewPostHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.custum_home_post, parent, false);
    return new NewPostHolder(view);
}

@Override
public void onBindViewHolder(@NonNull final NewPostHolder mHolder, final int position) {


    mHolder.tvSendername.setText(list.get(position).getSendername());
    mHolder.tvPostText.setText(list.get(position).getPosttext());
    mHolder.tvServiceType.setText(list.get(position).getServicetype());
    String datetime = list.get(position).getDatetime();
    MyDateTime myDateTime = new MyDateTime();
    String converteddatetime = myDateTime.getSaveTime(datetime);
    mHolder.tvDatetime.setText(converteddatetime);


    SharedPreferences prefs = context.getSharedPreferences("DholkaAppPref", Context.MODE_PRIVATE);
    String mUserid = prefs.getString("userid", "Couldn't load userid");

     final String postid=task.getResult().getDocuments().get(position).getId();


  if (mUserid.equalsIgnoreCase("LNvc0acRiaPioaKVnXasjkjEeYE2")) {
        if (list.get(position).getVerified().equalsIgnoreCase("no")) {
            mHolder.llPostAproval.setVisibility(View.VISIBLE);
            mHolder.btPostApprove.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    if (list.get(position).getVerified().equalsIgnoreCase("no")) {
                        PostApproval approval = new PostApproval(context, postid);
                    }
                }
            });
            mHolder.btPostDelete.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    String imagename = list.get(position).getPhotourl();
                    if (imagename.equalsIgnoreCase("nourl")) {
                        DocumentReference mPostref = FirebaseFirestore.getInstance().collection("posts").
                                document(postid);
                        mPostref.delete();
                    } else {
                        StorageReference mStorageref = FirebaseStorage.getInstance().getReferenceFromUrl(imagename);
                        mStorageref.delete();
                        DocumentReference mPostref = FirebaseFirestore.getInstance().collection("posts").
                                document(postid);
                        mPostref.delete();
                    }
                }
            });
        } else {
            mHolder.llPostAproval.setVisibility(View.GONE);
            mHolder.cardHome.setVisibility(View.VISIBLE);
        }
    } else {
        mHolder.llPostAproval.setVisibility(View.GONE);
    }
    if (mUserid.equalsIgnoreCase("LNvc0acRiaPioaKVnXasjkjEeYE2")) {



        mHolder.cardHome.setVisibility(View.VISIBLE);
        mHolder.cardHome.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {

                final AlertDialog.Builder builder = new AlertDialog.Builder(context);
                AlertDialog dialog;
                builder.setMessage(R.string.dialog_delete_post)
                        .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                // FIRE ZE MISSILES!
                                String imagename = list.get(position).getPhotourl();
                                if (imagename.equalsIgnoreCase("nourl")) {
                                    DocumentReference mPostref = FirebaseFirestore.getInstance().collection("posts").
                                            document(postid);
                                    mPostref.delete();
                                } else {
                                    StorageReference mStorageref = FirebaseStorage.getInstance().getReferenceFromUrl(imagename);
                                    mStorageref.delete();
                                    DocumentReference mPostref = FirebaseFirestore.getInstance().collection("posts").
                                            document(postid);
                                    mPostref.delete();
                                }
                            }
                        })
                        .setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.dismiss();
                            }
                        });
                dialog = builder.create();
                dialog.show();


                return false;
            }
        });
    } else {
        if (list.get(position).getVerified().equalsIgnoreCase("yes")) {
            mHolder.cardHome.setVisibility(View.VISIBLE);
        } else {
            mHolder.cardHome.setVisibility(View.GONE);
        }
    }
    String text = list.get(position).getPosttext();
    if (text.length() > 150) {
        text = text.substring(0, 150) + "...";
        mHolder.tvPostText.setText(Html.fromHtml(text + "<font color='green'> <u>Read More</u></font>"));
        mHolder.tvPostText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mHolder.tvPostText.setText(list.get(position).getPosttext());

            }
        });
    } else {
        mHolder.tvPostText.setText(list.get(position).getPosttext());
    }
    mHolder.tvTotalLike.setText("Likes : " + list.get(position).getTotal_like());
    mHolder.tvTotalComments.setText("Comments : " + list.get(position).getTotal_comment());

    final String photourl = list.get(position).getPhotourl();
    if (photourl.equalsIgnoreCase("nourl")) {
        mHolder.ivPostphoto.setVisibility(View.GONE);
    } else {
        mHolder.ivPostphoto.setVisibility(View.VISIBLE);
        FirebaseStorage fs = FirebaseStorage.getInstance();
        fs.getReferenceFromUrl(photourl);
        StorageReference mImageRef = fs.getReference();
        String ssss = fs.getReferenceFromUrl(photourl).getName();
        mImageRef.child("post_photos/" + ssss).getDownloadUrl()
                .addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {
                        mHolder.postImageUri = uri;
                           /* Picasso.with(holder.ivPostphoto.getContext()).
                                    load(uri).
                                    placeholder(R.drawable.ic_image_black_24dp).
                                    into(holder.ivPostphoto);*/
                       /* float thumb=0;
                        Glide.with(context).asBitmap()
                                .load(uri)
                                .thumbnail(thumb)
                                .into(mHolder.ivPostphoto);*/
                        Picasso.with(context).load(uri).fit().centerCrop()
                                .placeholder(R.drawable.ic_image_black_24dp)
                                .error(R.drawable.ic_image_black_24dp)
                                .into(mHolder.ivPostphoto);
                        //ivPostphoto.setImageURI(uri);


                    }
                }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
            }
        });
    }

    final String senderId = list.get(position).getSenderid();
    StorageReference mProfileRef =
            FirebaseStorage.getInstance().getReference();
    mProfileRef.child("profile_pic/" + senderId + ".jpg").getDownloadUrl()
            .addOnSuccessListener(new OnSuccessListener<Uri>() {
                @Override
                public void onSuccess(Uri uri) {
                    //   Picasso.with(context).load(uri).into(holder.ivSenderphoto);

                    Picasso.with(context).load(uri).fit().centerCrop()
                            .placeholder(R.drawable.ic_account_circle_black_24dp)
                            .error(R.drawable.ic_account_circle_black_24dp)
                            .into(mHolder.ivSenderphoto);


                }
            }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Picasso.with(context).load(R.drawable.ic_account_circle_black_24dp).fit().centerCrop()
                    .placeholder(R.drawable.ic_account_circle_black_24dp)
                    .error(R.drawable.ic_account_circle_black_24dp)
                    .into(mHolder.ivSenderphoto);
        }
    });
}

@Override
public int getItemCount() {
    return list.size();
}


public class NewPostHolder extends RecyclerView.ViewHolder {

    TextView tvSendername,tvDatetime,tvServiceType,tvPostText,tvTotalLike,tvTotalComments;
    ImageView ivSenderphoto;
    PhotoView ivPostphoto;
    ImageButton ibLike,ibComments,ibShare, ibCall, ibMap;
    LinearLayout llPostAproval;
    Button btPostApprove,btPostDelete;
    CardView cardHome;
    Uri postImageUri;
    View rootView;
    RelativeLayout rlPosts;
    View view;
    NewPostHolder(View itemView) {
        super(itemView);
        view = itemView;
        tvSendername=(TextView)itemView.findViewById(R.id.tv_poster_username);
        tvDatetime=(TextView)itemView.findViewById(R.id.tv_poster_datetime);
        tvServiceType=(TextView)itemView.findViewById(R.id.tv_poster_servicetype);
        tvPostText=(TextView)itemView.findViewById(R.id.tv_poster_text);
        tvTotalLike=(TextView)itemView.findViewById(R.id.tv_poster_total_likes);
        tvTotalComments=(TextView)itemView.findViewById(R.id.tv_poster_total_comments);
        ivSenderphoto=(ImageView)itemView.findViewById(R.id.iv_poster_photo);
        ivPostphoto=(PhotoView) itemView.findViewById(R.id.iv_poster_images);
        ibLike=(ImageButton)itemView.findViewById(R.id.ib_poster_like);
        ibComments=(ImageButton)itemView.findViewById(R.id.ib_poster_comments);
        ibShare=(ImageButton)itemView.findViewById(R.id.ib_poster_share);
        ibCall=(ImageButton)itemView.findViewById(R.id.ib_poster_call);
        ibMap=(ImageButton)itemView.findViewById(R.id.ib_poster_map);
        llPostAproval=(LinearLayout)itemView.findViewById(R.id.linearPosterApproval);
        btPostApprove=(Button)itemView.findViewById(R.id.bt_poster_approve);
        btPostDelete=(Button)itemView.findViewById(R.id.bt_poster_delete);
        cardHome=(CardView)itemView.findViewById(R.id.card_home_post);
        rlPosts=(RelativeLayout)itemView.findViewById(R.id.rl_home_posts);
        tvPostText.setTextIsSelectable(true);
    }


}

}

Now, my questions and i am getting difficulty to get Document Id after first three id(three id is my limit), after getting first three documents error is displayed belows. so kindly please help me about this to get next query documents id. hope you understands. thank you for your all help Error :

2020-02-15 16:56:56.138 22675-22675/app.burhani.dholkaapp E/AndroidRuntime: FATAL EXCEPTION: main
Process: app.burhani.dholkaapp, PID: 22675
java.lang.IndexOutOfBoundsException: Index: 3, Size: 3
    at java.util.ArrayList.get(ArrayList.java:437)
    at app.burhani.dholkaapp.newadapter.NewPostAdapter.onBindViewHolder(NewPostAdapter.java:81)
    at app.burhani.dholkaapp.newadapter.NewPostAdapter.onBindViewHolder(NewPostAdapter.java:47)
    at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7056)
    at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7098)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6010)
    at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6277)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6116)
    at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6112)
    at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
    at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
    at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
    at androidx.recyclerview.widget.LinearLayoutManager.scrollBy(LinearLayoutManager.java:1391)
    at androidx.recyclerview.widget.LinearLayoutManager.scrollVerticallyBy(LinearLayoutManager.java:1128)
    at androidx.recyclerview.widget.RecyclerView.scrollStep(RecyclerView.java:1841)
    at androidx.recyclerview.widget.RecyclerView$ViewFlinger.run(RecyclerView.java:5300)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1163)
    at android.view.Choreographer.doCallbacks(Choreographer.java:986)
    at android.view.Choreographer.doFrame(Choreographer.java:894)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1148)
    at android.os.Handler.handleCallback(Handler.java:883)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7682)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
Qutbuddin Bohra
  • 1,165
  • 1
  • 11
  • 29
  • 1
    It's obvious you are trying to get an item from an array at a position that does not exist. Try to use the debugger to see where the array has no element at a particular position. – Alex Mamo Feb 17 '20 at 08:56
  • If you are interested in a Firestore real-time pagination algorithm you can take a look this [example](https://github.com/alexmamo/FirestoreRealtimePagination), which is a repo for this [article](https://medium.com/firebase-tips-tricks/how-to-create-a-clean-firestore-pagination-with-real-time-updates-ce05a87bb902). – Alex Mamo Feb 17 '20 at 08:56
  • Yes, i know , error is i could not get document id after Next query is run. I actually need documents id because i require delete and update that documents. first query limited data document id i got but next query is showing error as above. please help me forf this. thank you – Qutbuddin Bohra Feb 23 '20 at 10:18
  • i got that why this happen!. because of 'task' task size have only 3 which is my limit for load data whatever while i scrolling view size always 3.. but still i don't resolve how to get document id after next query run – Qutbuddin Bohra Feb 24 '20 at 17:17

3 Answers3

0

It could be because you are sending the position and you that gives you the error, try to send final String postid=task.getResult().getDocuments().get(position-1).getId(); and see if you are getting the object that you want.Let me know it that works for you

Mateo Hervas
  • 545
  • 1
  • 5
  • 20
0

finally i solved error. the error is size of next query querysnapshot size. i use new List for saving document ids using this method on both side in first query and next quesry

           for (QueryDocumentSnapshot document : t.getResult()) {
                                                listId.add(document.getId());
                                            }

and in on Adapter get id using listId with position. final query code is

        Task<QuerySnapshot> mSnapy;
    boolean isScrolling = false;
    boolean isLastItemReached = false;
    DocumentSnapshot lastVisible;
    NewPostAdapter mNewPostAdapter;

    private void getNewFireData() {

        final int limit = 3;
        mRecyclerView = rootView.findViewById(R.id.rv_post_list);
        final LinearLayoutManager mManeger=new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(mManeger);
        mRecyclerView.setHasFixedSize(true);

        mRecyclerView.invalidate();
        final List<Posts> list = new ArrayList<>();
        final List<String> listId=new ArrayList<>();

        FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
        final CollectionReference postRef = rootRef.collection("posts");
        Query query = postRef.orderBy("datetime",
                Query.Direction.DESCENDING).limit(limit);
        query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
            @Override
            public void onComplete(@NonNull Task<QuerySnapshot> task) {


                if(task.isSuccessful()){

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

                    for (DocumentSnapshot document : task.getResult()) {
                        Posts postModel = document.toObject(Posts.class);
                        list.add(postModel);
                    }
                    for (QueryDocumentSnapshot document : task.getResult()) {
                        listId.add(document.getId());
                    }
                    mSnapy=task;
                    mNewPostAdapter = new NewPostAdapter(list,getActivity()
                            , mSnapy,listId,myContext);


                    mRecyclerView.addOnScrollListener(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 = postRef.orderBy("datetime",
                                        Query.Direction.DESCENDING).startAfter(lastVisible).limit(limit);
                                nextQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                                    @Override
                                    public void onComplete(@NonNull Task<QuerySnapshot> t) {
                                        if (t.isSuccessful()) {
                                            for (DocumentSnapshot d : t.getResult()) {
                                                Posts productModel = d.toObject(Posts.class);
                                                list.add(productModel);

                                            }
                                            for (QueryDocumentSnapshot document : t.getResult()) {
                                                listId.add(document.getId());
                                            }
                                            mSnapy = t;
                                            System.out.println("Task Data "+mSnapy.getResult().getDocuments());
                                            mNewPostAdapter.notifyDataSetChanged();

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

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

                        }
                    });

          //          mNewPostAdapter.setHasStableIds(true);

                    mRecyclerView.setAdapter(mNewPostAdapter);


                }

            }
        });

    }
Qutbuddin Bohra
  • 1,165
  • 1
  • 11
  • 29
0

I found another answer that code is below Just create a new obejct on Modal Post.class dodId and use it like below

                    for (QueryDocumentSnapshot document : task.getResult()) {
                        Posts modal=document.toObject(Posts.class);
                        modal.setDoc_id(document.getId());
                        list.add(modal);
                    }
Qutbuddin Bohra
  • 1,165
  • 1
  • 11
  • 29