如何在FirestorePagingAdapter中获取文档ID?

时间:2019-05-09 15:08:52

标签: java android firebase google-cloud-firestore android-paging

我正在尝试使用FirestorePagingAdapter显示Firestore数据库中所有用户的列表。我使用FirestorePagingAdapter而不是FirestoreRecyclerAdapter来最大程度地减少读取次数,因为F irestorePagingAdapter不会读取整个文档列表,而FirestoreRecyclerAdapter却会读取整个文档列表。我能够成功显示分页列表,但是我需要在其上实现onClickListener,并且在单击每个项目时,我需要打开另一个活动,该活动显示了所单击的特定用户的详细说明。为此,我需要将被点击用户的documentId传递给下一个活动。

但是不幸的是, FirestorePagingAdapter没有getSnapshots()方法,因此我使用getSnapshots()。getSnapshot(position).getId()。

另一方面,FirestoreRecyclerAdapter具有此方法,这使获取文档ID变得非常容易。像这样的东西:How to get document id or name in Android in Firestore db for passing on to another activity?

// Query to fetch documents from user collection ordered by name
Query query = FirebaseFirestore.getInstance().collection("users")
                .orderBy("name");

// Setting the pagination configuration
PagedList.Config config = new PagedList.Config.Builder()
                .setEnablePlaceholders(false)
                .setPrefetchDistance(10)
                .setPageSize(20)
                .build();


FirestorePagingOptions<User> firestorePagingOptions = new FirestorePagingOptions.Builder<User>()
                .setLifecycleOwner(this)
                .setQuery(query, config, User.class)
                .build();

firestorePagingAdapter =
                new FirestorePagingAdapter<User, UserViewHolder>(firestorePagingOptions){

                    @NonNull
                    @Override
                    public UserViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                        View view = LayoutInflater.from(parent.getContext())
                                .inflate(R.layout.single_user_layout, parent, false);

                        return new UserViewHolder(view);
                    }

                    @Override
                    protected void onBindViewHolder(@NonNull UserViewHolder holder, int position, @NonNull User user) {
                        holder.setUserName(user.name);
                        holder.setStatus(user.status);
                        holder.setThumbImage(user.thumb_image, UsersActivity.this);


                        holder.mView.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                Intent userProfileIntent = new Intent(UsersActivity.this, UserProfileActivity.class);
                                // Need to fetch the user_id to pass it as intent extra
                                // String user_id = getSnapshots().getSnapshot(position).getId();
                                // userProfileIntent.putExtra("user_id", user_id);
                                startActivity(userProfileIntent);
                            }
                        });
                    }
                };

5 个答案:

答案 0 :(得分:1)

在尝试从 itemView 访问文档快照时,我发现 this

itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int pos = getAdapterPosition();
                if (pos != RecyclerView.NO_POSITION && listener != null) {
                    String docId = getItem(pos).getId();
                    Toast.makeText(context, "doc Id: "+docId, Toast.LENGTH_SHORT).show();
                    //listener.onItemClick(getSnapshots().getSnapshot(pos), pos, docId);
                    listener.onItemClick(getItem(pos), pos, docId); 
                }
            }
        });

正如前面提到的 heregetItem() 返回项目的数据对象。

答案 1 :(得分:0)

您已经注意到:

String id = getSnapshots().getSnapshot(position).getId();

无效,仅在使用FirestoreRecyclerAdapter时有效。因此,要解决此问题,您需要将文档的ID存储为文档的属性。如果文档的ID是来自Firebase认证的用户的ID,则只需存储该uid。如果您不使用uid,则在创建这样的新对象时,获取文档ID并将其传递给User构造函数:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference usersRef = rootRef.collection("users");
String id = eventsRef.document().getId();
User user = new User(id, name, status, thumb_image);
usersRef.document(id).set(user);

答案 2 :(得分:0)

我能够通过在SnapshotParser方法中使用setQuery来做到这一点。通过此操作,我能够修改从Firestore获得的对象。 documentSnapshot.getId()方法返回文档ID。

FirestorePagingOptions<User> firestorePagingOptions = new FirestorePagingOptions.Builder<User>()
                .setLifecycleOwner(this)
                .setQuery(query, config, new SnapshotParser<User>() {
                    @NonNull
                    @Override
                    public User parseSnapshot(@NonNull DocumentSnapshot snapshot) {
                        User user = snapshot.toObject(User.class);
                        user.userId = snapshot.getId();
                        return user;
                    }
                })
                .build();

在User类中,我只是在User类中添加了另一个字段“ String userId”。我的Firestore文档中不存在userId字段。 然后,在onClickListener中,我可以直接使用user.userId获取文档ID并将其发送到其他活动。

答案 3 :(得分:0)

由于我现在正在使用FirestorePagingAdapter,所以花了一天的时间来尝试获取文档的ID。对于Kotlin来说,这就是对我有用的

override fun onBindViewHolder(viewHolder: LyricViewHolder, position: Int, song: Lyric) {
                // Bind to ViewHolder
                viewHolder.bind(song)

                viewHolder.itemView.setOnClickListener { view ->

                    val id = getItem(position)?.id

                    var bundle = bundleOf("id" to id)
                    view.findNavController().navigate(R.id.songDetailFragment, bundle)
                }
            }

希望这会在不久的将来对他人有所帮助。可以发布完整代码并充分解释是否有人感到困惑。编码愉快!

答案 4 :(得分:-1)

尝试使用此

getSnapshots().getSnapshot(position).getId()