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来最小化读取次数,因为FirestorePagingAdapter
不读取整个文档列表,而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);
}
}
});