You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)
);

运行结果:查询正常执行,无错误。

解决方案

  1. 升级至cloud_firestore 4.10.0及以上版本:后续版本已修复该类型转换问题,升级后可直接使用原代码逻辑。
  2. 改用链式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);
  1. 临时转换为路径字符串查询:将DocumentReference转换为路径字符串存储,查询时使用字符串匹配:
// 存储数据时,将itemReference替换为itemReference.path
// 查询时:
Filter(PostKeys.ingredients, arrayContains: itemReference.path)

注意:此方法会丢失DocumentReference的直接关联,后续需手动将路径转换回DocumentReference。

内容的提问来源于stack exchange,提问作者byron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 03:43:13