Firestore事务中是否可以为新建文档创建并写入嵌套子集合?
Firestore事务子集合写入权限问题解答
Firestore 本身完全支持在单个事务中为新创建的父文档写入子集合,你遇到的权限报错本质是安全规则的校验逻辑触发的,和事务本身的能力无关。
报错原因解释
Firestore 的安全规则校验是在事务整体提交阶段一次性对所有写入操作做校验,不会按事务内的操作顺序分步校验:
- 你在同一个事务中同时写入
yDocRef和它的子文档zDocRef时,安全规则校验读取的是事务提交前的数据库快照,此时父文档y还未实际写入,如果你配置的y下z集合的写入权限要求「父文档y必须已存在」,就会触发权限不足的报错。 - 你把
zDocRef的写入移到事务外后,事务已经提交完成,父文档y已经真实存在于数据库中,此时执行zDocRef.set时安全规则校验能读取到已存在的父文档,自然就通过校验。
修复方案
- 方案1:调整安全规则逻辑,将
z集合写入权限中校验父文档存在的逻辑,从exists()改为existsAfter()。existsAfter()会判断操作提交完成后的文档状态,刚好适配同事务同时写入父子文档的场景,示例规则参考:
match /y/{yId}/z/{zId} { allow write: if existsAfter(/databases/$(database)/documents/y/$(yId)); }
- 方案2:如果不需要
z文档的写入和前面的操作保持原子性,可以保留你现在的写法,把z的写入放到事务外即可,注意要额外处理事务失败的场景,避免父文档写入失败时还多写了无效的子文档。
内容的提问来源于stack exchange,提问作者corsair
相关产品推荐
相关产品推荐

