Flutter cloud_firestore使用Filter搭配DocumentReference触发无效参数错误
Flutter Cloud Firestore 4.9.3中Filter结合arrayContains查询DocumentReference报错问题及解决方案
我们在使用Flutter的cloud_firestore包(已升级至4.9.3版本)时,执行包含arrayContains: DocumentReference的Filter查询(无论是否嵌套在Filter.or中),都会触发错误:Invalid argument: Instance of '_JsonDocumentReference'。
问题复现
含Filter.or的查询代码
.where( Filter.and( Filter(PostKeys.type, whereIn: [PostType.creation.name, PostType.combination.name]), Filter(PostKeys.visibility, isEqualTo: ContentVisibility.public.name), Filter.or( Filter(PostKeys.ingredients, arrayContains: itemReference), Filter(PostKeys.tags, arrayContains: itemReference) ) ) ) .orderBy(PostKeys.created, descending: true) .limit(queryLimit);
错误结果:Invalid argument: Instance of '_JsonDocumentReference'
移除Filter.or后的查询代码
.where( Filter.and( Filter(PostKeys.type, whereIn: [PostType.creation.name, PostType.combination.name]), Filter(PostKeys.visibility, isEqualTo: ContentVisibility.public.name), Filter(PostKeys.ingredients, arrayContains: itemReference), ) ) .orderBy(PostKeys.created, descending: true) .limit(queryLimit);
错误结果:Invalid argument: Instance of '_JsonDocumentReference'
背景说明
cloud_firestore 4.9.2版本的更新日志标注了“FIX(firestore): allow DocumentReference to be used to in Filter queries”,但该修复在4.9.3版本中未生效。而相同逻辑的查询在JavaScript(Web V9)环境中可正常运行:
JavaScript参考代码
pq = query(collection(db, "posts"), and( where('type', "in", ['creation','combination']), where("visibility", "==", CONSTANTS.visibility.public), or( where('ingredients', "array-contains", itemRef), where('tags', "array-contains", itemRef) ) ), orderBy("created","desc"), limit(queryLimit) );
运行结果:查询正常执行,无错误。
解决方案
- 升级至cloud_firestore 4.10.0及以上版本:后续版本已修复该类型转换问题,升级后可直接使用原代码逻辑。
- 改用链式where调用替代Filter组合:放弃使用
Filter.and包裹所有条件,改用传统链式where方法拆分条件,示例:
.where(PostKeys.type, whereIn: [PostType.creation.name, PostType.combination.name]) .where(PostKeys.visibility, isEqualTo: ContentVisibility.public.name) .where(Filter.or( Filter(PostKeys.ingredients, arrayContains: itemReference), Filter(PostKeys.tags, arrayContains: itemReference) )) .orderBy(PostKeys.created, descending: true) .limit(queryLimit);
- 临时转换为路径字符串查询:将
DocumentReference转换为路径字符串存储,查询时使用字符串匹配:
// 存储数据时,将itemReference替换为itemReference.path // 查询时: Filter(PostKeys.ingredients, arrayContains: itemReference.path)
注意:此方法会丢失DocumentReference的直接关联,后续需手动将路径转换回DocumentReference。
内容的提问来源于stack exchange,提问作者byron
相关产品推荐
相关产品推荐

