Firestore跨集合查询获取用户服务商列表无返回结果问题
问题背景
现有包含users集合在内的两个集合,需要实现为单个用户生成对应服务商列表的功能。集合结构参考如下:
编写如下代码尝试实现需求,但运行后无法返回预期结果,无法定位错误:
Future<List<ServineraProvider>> getfavoritesForUser() async{ List<ServineraProvider> providers = []; await providerSkillsCollection.where('providerID', isEqualTo: this.uid).get() .then((onValue){ for(int i=0; i<onValue.docs.length; i++){ var doc = onValue.docs[i].data() as Map<String,dynamic>; print(doc['skillID']); skillsCollection.doc(doc['skillID']).get() .then((doc){ var data = doc.data() as Map<String,dynamic>; providers.add(ServineraProvider( providerID: data['providerID'], providerName: data['providerName'], providerEmail: data['providerEmail'], providerPhoneNumber: data['providerPhoneNumber'], providerPicture: data['providerPicture'], providerState: data['providerState'], providerStatus: data['providerStatus'] ) ); }); } }); return providers; }
错误原因
- 核心问题是异步等待缺失:外层的
await只会等待providerSkillsCollection的查询完成,循环内部的skillsCollection.doc().get()是独立异步任务,没有被await等待,代码执行到return providers时,这些内部查询还没执行完,providers列表还没完成数据填充,自然返回不了正确结果。 - 查询条件存在逻辑错误:要获取当前用户关联的服务商,第一层查询不应该用
providerID匹配当前用户的uid,应该用集合中存储用户关联ID的字段做筛选,否则查出来的是当前用户自己作为服务商的关联技能,不是用户关联的目标服务商。
修正后可运行代码
Future<List<ServineraProvider>> getfavoritesForUser() async { List<ServineraProvider> providers = []; // 第一层查询:拿到当前用户关联的所有服务商关联记录 // 注意:where里的字段名请替换为你集合中实际存储用户ID的字段,不要硬抄userID final relatedQuery = await providerSkillsCollection.where('userID', isEqualTo: uid).get(); // 批量构造所有服务商详情查询任务,统一等待执行 final providerQueryTasks = relatedQuery.docs.map((recordDoc) async { final recordData = recordDoc.data() as Map<String, dynamic>; final providerDoc = await skillsCollection.doc(recordData['skillID']).get(); final providerData = providerDoc.data() as Map<String, dynamic>; return ServineraProvider( providerID: providerData['providerID'], providerName: providerData['providerName'], providerEmail: providerData['providerEmail'], providerPhoneNumber: providerData['providerPhoneNumber'], providerPicture: providerData['providerPicture'], providerState: providerData['providerState'], providerStatus: providerData['providerStatus'] ); }).toList(); // 等所有服务商查询完成后再返回结果 providers = await Future.wait(providerQueryTasks); return providers; }
关键修改说明
- 全部异步逻辑统一用
async/await处理,替换容易漏等待的嵌套.then()回调,代码可读性更高 - 用
Future.wait批量等待所有并行的服务商详情查询,保证所有数据都拉取完成后再返回列表,不会出现返回空列表的问题 - 标注了第一层查询的筛选逻辑注意点,避免查错数据范围
内容的提问来源于stack exchange,提问作者esraakd
相关产品推荐
相关产品推荐

