iOS Firestore中queryWhereField与queryOrderedByField查询失效问题
问题分析与修复方案
嗨,我一眼就瞅到你的代码问题啦!你明明构建了带过滤条件和排序的查询链,但根本没把这个加工好的查询对象用上,直接用原始的集合引用colRef去拉数据,那过滤和排序自然完全没生效,可不就返回全量数据还不排序嘛😂
修正后的完整代码
defFirestore = [FIRFirestore firestore]; colRef = [defFirestore collectionWithPath:@"walks"]; // 重点:把链式构建的查询保存到变量里 FIRQuery *filteredQuery = [[[colRef queryWhereField:@"requestId" isEqualTo:@(self.requestId)] queryWhereField:@"taskId" isEqualTo:@(self.taskId)] queryOrderedByField:@"createdDate"]; // 用这个加工好的查询对象发起请求,而不是原始的colRef [filteredQuery getDocumentsWithCompletion:^(FIRQuerySnapshot * _Nullable snapshot, NSError * _Nullable error) { if (error != nil) { NSLog(@"Error getting documents: %@", error); // 这里注意:如果报错提示需要创建复合索引,直接点控制台里的链接去Firestore控制台创建就行 } else { for (FIRDocumentSnapshot *document in snapshot.documents) { NSLog(@"%@ => %@", document.documentID, document.data); } } }];
核心原因解释
Firestore的查询方法(比如queryWhereField:、queryOrderedByField:)都是返回一个全新的查询对象,不会修改你原来的colRef集合引用。所以你之前的链式调用相当于白做了,没把结果存下来就直接用原集合拉数据,当然没效果。
另外补充两个要注意的点:
- 确认
self.requestId和self.taskId的类型和Firestore里存的一致(从你提供的数据库内容看,这俩字段是数字类型,你用@()包装成NSNumber是对的)。 - 这种多过滤条件+排序的查询需要复合索引,如果运行后控制台报错说缺少索引,直接点报错里的链接去Firestore控制台创建就行,一步到位很方便。
内容的提问来源于stack exchange,提问作者Mohammad Ashraful Kabir
相关产品推荐
相关产品推荐

