聊天应用如何从Firestore数据库仅查询展示设备通讯录内存在的用户
解决方案
问题根因
你目前的实现是先拉取所有非当前用户的账号数据,再在适配器绑定逻辑里判断是否在通讯录中,未匹配的条目没有做隐藏处理,所以会出现大量空白默认条目。
优化方案
直接通过Firestore的whereIn条件查询,仅拉取手机号在通讯录列表内的用户数据,从数据源层面过滤无效条目,无需在适配器中二次判断。
核心修改点
- 调整查询逻辑
替换原有全局查询,使用通讯录列表作为查询条件:
// 原有代码 // Query query = firebaseFirestore.collection("Users").whereNotEqualTo("uid", firebaseAuth.getUid()); // 替换为 if (getcontactList.isEmpty()) { // 通讯录为空时可自行添加空布局提示逻辑 return view; } // Firestore whereIn 单次最多支持30个匹配值,通讯录超过30人需拆分查询 Query query = firebaseFirestore.collection("Users") .whereIn("contact", getcontactList) .whereNotEqualTo("uid", firebaseAuth.getUid());
首次运行会触发索引创建提示,按照日志中的链接跳转创建对应复合索引即可正常查询。
- 修复图片绑定BUG
原有全局声明的imageViewOfUser会导致列表滑动时图片加载错乱,将其移到ViewHolder内部作为成员变量:
public class NoteViewHolder extends RecyclerView.ViewHolder{ private TextView particularusername; private TextView statusofuser; // 新增ViewHolder内部图片控件声明 public ImageView imageViewOfUser; public NoteViewHolder(@NonNull View itemView) { super(itemView); particularusername = itemView.findViewById(R.id.nameofuser); statusofuser = itemView.findViewById(R.id.statusofuser); imageViewOfUser = itemView.findViewById(R.id.imageviewofuser); } }
- 简化适配器绑定逻辑
查询已经完成过滤,无需再遍历通讯录匹配:
@Override protected void onBindViewHolder(@NonNull NoteViewHolder noteViewHolder, int i, @NonNull firebasemodel firebasemodel) { noteViewHolder.particularusername.setText(firebasemodel.getName()); String uri = firebasemodel.getImage(); Picasso.get().load(uri).into(noteViewHolder.imageViewOfUser); if ("Online".equals(firebasemodel.getStatus())) { noteViewHolder.statusofuser.setText(firebasemodel.getStatus()); noteViewHolder.statusofuser.setTextColor(Color.rgb(66, 133, 244)); } else { noteViewHolder.statusofuser.setText(firebasemodel.getStatus()); } noteViewHolder.itemView.setOnClickListener(v -> Toast.makeText(getActivity(), "Clicked on particular user", Toast.LENGTH_SHORT).show() ); }
通讯录超过30人处理方案
Firestore的whereIn单次查询最多支持30个匹配值,如果你的通讯录人数超过30,将通讯录列表拆分为每30个一组,分别发起查询,合并所有查询结果后使用普通RecyclerView.Adapter绑定即可。
注意事项
确保Firestore的Users集合中存储的contact字段格式和系统通讯录获取的NORMALIZED_NUMBER格式完全一致(统一带国家码格式),否则会出现匹配失败的情况。
参考效果:
内容的提问来源于stack exchange,提问作者Vimu Rk
相关产品推荐
相关产品推荐

