问题
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)
回答1:
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
回答2:
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);
}
}
});
}
回答3:
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);
}
来源:https://stackoverflow.com/questions/60247307/how-to-get-documents-id-firestore-paginate