如何从Firestore排除当前用户获取数据,存储到Contacts并在RecyclerView展示
问题解决方案
数据库结构说明
- Firestore中的用户整体结构
- 单个用户字段信息(包含uId、fullName、fullNum、status、image、presence等)
需求
获取当前用户以外的所有用户数据,将其存入当前用户文档下的Contacts子集合(路径:Users/{当前用户uId}/Contacts),之后在RecyclerView中展示这些联系人数据。
现有代码问题
你的代码中存储联系人的路径错误,当前写的是Contacts/{uId}/rooms,但实际需要的是Users/{uId}/Contacts,这会导致数据存到错误位置,后续无法正确读取。另外循环中逐个添加文档可以优化为批量写入,提升效率。
修正后的代码
1. 批量同步联系人数据
val uId = auth.currentUser?.uid ?: return // 空安全处理,避免空指针 val firestore = FirebaseFirestore.getInstance() // 获取除当前用户外的所有用户 firestore.collection("Users").whereNotEqualTo("uId", uId).get() .addOnSuccessListener { documents -> val batch = firestore.batch() val contactsCollection = firestore.collection("Users").document(uId).collection("Contacts") documents.forEach { document -> val contactData = hashMapOf( "uId" to document.getString("uId") ?: "", "fullName" to document.getString("fullName") ?: "", "fullNum" to document.getString("fullNum") ?: "", "image" to document.getString("image") ?: "", "presence" to document.getString("presence") ?: "", "status" to document.getString("status") ?: "" // 保留原字段 ) // 用对方的uId作为文档ID,避免重复添加 val contactDoc = contactsCollection.document(document.getString("uId") ?: "") batch.set(contactDoc, contactData) } // 执行批量写入 batch.commit().addOnSuccessListener { Toast.makeText(context, "联系人同步成功", Toast.LENGTH_SHORT).show() }.addOnFailureListener { Toast.makeText(context, "联系人同步失败", Toast.LENGTH_SHORT).show() } } .addOnFailureListener { Toast.makeText(context, "获取用户列表失败", Toast.LENGTH_SHORT).show() }
2. 读取Contacts数据到RecyclerView
首先定义联系人数据类:
data class Contact( val uId: String = "", val fullName: String = "", val fullNum: String = "", val image: String = "", val presence: String = "", val status: String = "" )
然后监听Contacts集合数据并更新RecyclerView:
val uId = auth.currentUser?.uid ?: return val contactsCollection = firestore.collection("Users").document(uId).collection("Contacts") val contactList = mutableListOf<Contact>() val adapter = ContactAdapter(contactList) // 自定义RecyclerView适配器 // 添加实时监听(或单次获取) contactsCollection.addSnapshotListener { snapshot, error -> if (error != null) { Toast.makeText(context, "读取联系人失败", Toast.LENGTH_SHORT).show() return@addSnapshotListener } contactList.clear() snapshot?.documents?.forEach { doc -> val contact = doc.toObject(Contact::class.java) contact?.let { contactList.add(it) } } adapter.notifyDataSetChanged() }
关键说明
- 路径修正:将联系人数据存入
Users/{uId}/Contacts,符合需求的存储路径 - 批量写入:用
WriteBatch代替循环逐个添加,减少网络请求次数,提升性能 - 文档ID:用联系人的uId作为文档ID,避免重复添加同一联系人
- 空安全处理:用
?:处理字段为空的情况,避免崩溃 - 实时监听:使用
snapshotListener可以实时同步联系人数据的变化
内容的提问来源于stack exchange,提问作者Mahmoud Nabil
相关产品推荐
相关产品推荐

