Java 如何在FirestorePagingAdapter中获取文档id?

Java 如何在FirestorePagingAdapter中获取文档id?,java,android,firebase,google-cloud-firestore,android-paging,Java,Android,Firebase,Google Cloud Firestore,Android Paging,我正在尝试使用FirestorePagingAdapter显示firestore数据库中所有用户的列表。我正在使用FirestorePagingAdapter而不是FirestoreRecyclerAdapter来最小化读取次数,因为FirestorePagingAdapter不读取整个文档列表,而FirestoreRecyclerAdapter读取。我能够成功地显示分页列表,但我需要在其上实现onClickListener,在单击每个项目时,我需要打开另一个活动,该活动显示所单击的特定用户的详

我正在尝试使用
FirestorePagingAdapter
显示firestore数据库中所有用户的列表。我正在使用
FirestorePagingAdapter
而不是FirestoreRecyclerAdapter来最小化读取次数,因为F
irestorePagingAdapter
不读取整个文档列表,而
FirestoreRecyclerAdapter
读取。我能够成功地显示分页列表,但我需要在其上实现
onClickListener
,在单击每个项目时,我需要打开另一个活动,该活动显示所单击的特定用户的详细描述。为此,我需要将单击用户的documentId传递给下一个活动

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

另一方面,FirestoreRecyclerAdapter有这种方法,使得获取文档id成为一项非常简单的任务。大概是这样的:

//从按名称排序的用户集合中获取文档的查询
Query Query=FirebaseFirestore.getInstance().collection(“用户”)
.订购人(“名称”);
//设置分页配置
PagedList.Config Config=new PagedList.Config.Builder()
.setEnablePlaceholders(false)
.设置预取距离(10)
.setPageSize(20)
.build();
FirestorePagingOptions FirestorePagingOptions=新建FirestorePagingOptions.Builder()
.setLifecycleOwner(此)
.setQuery(查询、配置、用户.class)
.build();
防火袋适配器=
新FirestorePagingAdapter(firestorePagingOptions){
@非空
@凌驾
public UserViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType){
View=LayoutInflater.from(parent.getContext())
.充气(R.layout.single_user_layout,parent,false);
返回新的UserViewHolder(视图);
}
@凌驾
受保护的无效onBindViewHolder(@NonNull UserViewHolder holder,int位置,@NonNull User){
holder.setUserName(user.name);
持有者设置状态(用户状态);
setThumbImage(user.thumb\u image,UsersActivity.this);
holder.mView.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
Intent userProfileIntent=新意图(UsersActivity.this,UserProfileActivity.class);
//需要获取用户\u id才能将其作为intent extra传递
//字符串user_id=getSnapshots().getSnapshot(位置).getId();
//userProfileIntent.putExtra(“用户id”,用户id);
startActivity(userProfileIntent);
}
});
}
};

正如您已经注意到的:

String id = getSnapshots().getSnapshot(position).getId();
不起作用,它仅在使用
FirestoreRecyclerAdapter
时起作用。所以要解决这个问题,您需要将文档的id存储为文档的属性。如果文档的id是来自Firebase自动验证的用户id,则只需存储
uid
。如果未使用
uid
,请在创建如下新对象时获取文档id并将其传递给
用户
构造函数:

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

我可以通过在
setQuery
方法中使用
SnapshotParser
来实现这一点。通过这个,我能够修改我从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();
FirestorePagingOptions FirestorePagingOptions=newfirestorepagingoptions.Builder()
.setLifecycleOwner(此)
.setQuery(查询、配置、新快照解析器(){
@非空
@凌驾
公共用户解析快照(@NonNull DocumentSnapshot snapshot){
User=snapshot.toObject(User.class);
user.userId=snapshot.getId();
返回用户;
}
})
.build();
在User类中,我刚刚在User类中添加了另一个字段“stringuserid”。我的firestore文档中不存在userId字段。 在
onClickListener
中,我可以直接使用
user.userId
获取文档id并将其发送到其他活动。

尝试使用此选项

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

我花了一天时间试图获取文档的id,因为我现在正在使用FirestorePagingAdapter。对科特林来说,这对我很有效

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

希望这能在不久的将来帮助别人。如果有人感到困惑,可以发布完整的代码并进行充分解释。快乐编码

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


如前所述,
getItem()
返回项目的数据对象。

这是一种正确的方法,还是应该创建自己的适配器来扩展
FirestoreRecyclerAdapter
,然后使用查询游标对数据进行分页()。是的,这是正确的方法。在这种情况下,不需要创建自定义适配器,因为您只需将用户id传递给构造函数,然后在
onClick()
方法中使用
user.id
。Alex,请参阅。我找到了一种中间方法,既不需要在文档中存储uid,也不需要使用自定义适配器。这是一个很好的解决方案,但它只能在本地解决问题。我为什么这么说?如果你以后在项目中发现自己处于需要改变的位置
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)
                }
            }
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); 
                }
            }
        });