如何获取文档ID?Firestore分页

3

我正在使用Firebase Firestore数据库,尝试使用双查询来加载数据以进行分页recyclerview的数据。 我使用了Stackoverflow答案链接

我的代码是为了recycerview加载数据

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;
                                            }
                                        }
                                    }
                                });
                            }

                        }
                    });


                }

            }
        });



    }

视图持有器和适配器类是什么。
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);
    }


}

现在,我的问题是在获取前三个文档的id(三个id是我的限制)后,我很难获取文档ID,在获取了前三个文档后,出现以下错误。所以请帮助我获取下一个查询文档的id。谢谢你的所有帮助。 错误信息:

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
很明显,您正在尝试从不存在的位置获取数组中的项。尝试使用调试器查看数组在特定位置没有元素的位置。 - Alex Mamo
如果您对Firestore实时分页算法感兴趣,可以查看此示例,这是针对此文章的存储库。 - Alex Mamo
是的,我知道,错误在于我无法在运行Next查询后获取文档ID。实际上,我需要文档ID,因为我需要删除和更新这些文档。第一个查询限制了数据文档ID,但下一个查询显示了上述错误。请帮助我解决这个问题。谢谢。 - Qutbuddin Bohra
我明白为什么会发生这种情况!因为“任务”任务大小只有3,这是我在滚动视图时加载数据的限制。虽然视图大小始终为3,但我仍然不知道如何在下一个查询运行后获取文档ID。 - Qutbuddin Bohra
3个回答

0

可能是因为您正在发送位置并且导致错误,请尝试发送final String postid=task.getResult().getDocuments().get(position-1).getId();并查看是否获得了所需的对象。让我知道它是否对您有用。


0

终于解决了错误。错误是下一个查询的querysnapshot大小。我在第一个查询和下一个查询中都使用了新的List来保存文档ID,使用了这种方法。

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

Adapter 中使用 listId 和位置获取 id。 最终查询代码为

        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);


                }

            }
        });

    }

0

我找到了另一个答案,代码如下:只需在模态框上创建一个新对象Post.class dodId,并像下面这样使用它:

                    for (QueryDocumentSnapshot document : task.getResult()) {
                        Posts modal=document.toObject(Posts.class);
                        modal.setDoc_id(document.getId());
                        list.add(modal);
                    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接