Firestore查询问题:如何获取指定ID关联的rooms子集合数据?
解决方案
方法一:使用集合组查询(推荐)
Firestore支持集合组查询,可直接查询所有名为rooms的子集合,无需先遍历properties文档,这种方式更高效、代码更简洁。
实现代码
override fun get(userId: String): Flow<RoomsResponse> = callbackFlow { // 创建集合组查询,匹配所有rooms子集合中huurder字段等于指定userId的文档 val query = dbRef.collectionGroup("rooms").whereEqualTo("huurder", userId) val snapshotListener = query.addSnapshotListener { snapshot, e -> val roomsResponse = if (snapshot != null && !snapshot.isEmpty) { val rooms = snapshot.toObjects(Room::class.java) Response.Success(rooms) } else if (snapshot?.isEmpty == true) { Response.Success(emptyList()) // 无匹配房间时返回空列表 } else { Response.Failure(e ?: Exception("未知错误")) } trySend(roomsResponse).isSuccess } awaitClose { snapshotListener.remove() } }
注意事项
- 需为
rooms集合的huurder字段创建集合组索引,否则查询会失败并返回索引创建提示链接,按提示操作即可。
方法二:分步查询(先过滤properties,再查询子集合)
如果需要先筛选出huurders数组包含目标userId的properties文档,再查询这些文档下的rooms子集合,可采用此方式。
实现代码
override fun get(userId: String): Flow<RoomsResponse> = callbackFlow { val propertiesQuery = dbRef.collection("properties").whereArrayContains("huurders", userId) val snapshotListener = propertiesQuery.addSnapshotListener { propertiesSnapshot, e -> if (e != null) { trySend(Response.Failure(e)).isSuccess return@addSnapshotListener } if (propertiesSnapshot == null || propertiesSnapshot.isEmpty) { trySend(Response.Success(emptyList())).isSuccess return@addSnapshotListener } // 遍历符合条件的properties文档,查询其rooms子集合 val roomTasks = propertiesSnapshot.documents.map { propertyDoc -> propertyDoc.reference.collection("rooms") .whereEqualTo("huurder", userId) .get() } // 等待所有子查询完成,合并结果 Tasks.whenAllSuccess<QuerySnapshot>(roomTasks) .addOnSuccessListener { results -> val allRooms = mutableListOf<Room>() results.forEach { roomSnapshot -> allRooms.addAll(roomSnapshot.toObjects(Room::class.java)) } trySend(Response.Success(allRooms)).isSuccess } .addOnFailureListener { exception -> trySend(Response.Failure(exception)).isSuccess } } awaitClose { snapshotListener.remove() } }
原代码问题说明
- 查询目标错误:直接查询
properties集合而非rooms子集合,无法获取房间数据 - 查询参数缺失:
whereArrayContains未指定字段(应为huurders)和匹配值(传入的userId) - 类型转换错误:将
properties文档快照直接转为Room对象,类型不匹配
内容的提问来源于stack exchange,提问作者driesaster
相关产品推荐
相关产品推荐

