如何查询归一化设计的Firestore数据库,通过用户名获取好友列表
实现方案
首先建议先对齐Firestore常用最佳实践调整数据结构(若可修改):将Accounts集合的文档ID直接设为对应用户的UID,文档内存储username等用户属性,后续查询效率会更高。
具体实现分为两步:
步骤1:查询当前用户的全部好友关联记录
先拿到当前登录用户的UID(记为currentUid),查询Friends集合中members字段包含当前UID的所有文档,提取出所有好友的UID:
// Android Kotlin 示例代码 val db = FirebaseFirestore.getInstance() val currentUid = FirebaseAuth.getInstance().currentUser?.uid ?: return db.collection("Friends") .whereArrayContains("members", currentUid) .get() .addOnSuccessListener { querySnapshot -> val friendUidList = mutableListOf<String>() for (doc in querySnapshot.documents) { val members = doc.get("members") as List<String> // 排除当前用户自己的UID,剩下的就是好友UID val friendUid = members.first { it != currentUid } friendUidList.add(friendUid) } // 批量查询好友的用户名信息 queryFriendUsernames(friendUidList) }
如果你的members字段是Set类型,上述取值逻辑完全一致
步骤2:批量查询好友用户名
拿到所有好友UID列表后,用in查询一次性从Accounts集合拉取对应用户数据,避免逐次查询的性能损耗:
private fun queryFriendUsernames(friendUidList: List<String>) { val db = FirebaseFirestore.getInstance() // Firestore的in查询最多支持10个匹配项,好友数超过10个需要拆分批次查询 val batchSize = 10 val queryBatches = friendUidList.chunked(batchSize) val friendDisplayList = mutableListOf<FriendItem>() // FriendItem是你自定义的数据类,存储展示需要的uid、username等字段 queryBatches.forEach { batch -> db.collection("Accounts") // 若Accounts文档ID不是UID,而是文档内存储uid字段,可替换为.whereIn("uid", batch) .whereIn(FieldPath.documentId(), batch) .get() .addOnSuccessListener { snapshot -> for (doc in snapshot.documents) { val username = doc.getString("username") ?: "" val uid = doc.id friendDisplayList.add(FriendItem(uid, username)) } // 所有批次查询完成后,给RecyclerView Adapter更新数据 if (friendDisplayList.size == friendUidList.size) { yourRecyclerAdapter.updateList(friendDisplayList) } } } }
可选优化:冗余存储降低查询次数
如果好友列表是高频使用场景,可以直接在Friends文档中冗余存储两个成员的用户名,仅需一次查询就能拿到所有展示需要的数据,无需二次查询Accounts集合:
冗余存储需要注意数据同步:用户修改用户名时,需要同时更新所有关联的
Friends文档中的对应用户名字段,避免数据不一致。
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

