Firestore规则创建唯一ID文档报错:exists函数调用异常排查
Firestore安全规则判断文档唯一性报错问题解析
问题背景
需求:仅当不存在相同ID的文档时,才允许在Firestore中创建文档。
用户编写的Security Rules规则如下:
match /{AppNode}/Documents/BlueBooks/{bookId} { function isUniqueBlueBook() { return !exists(/databases/$(database)/Main/Documents/BlueBooks/$(request.resource.id)); } allow create: if isUniqueBlueBook(); }
执行时报错:
false for 'update' @ L5, Service call error. Function: [exists], Argument: [path_value { segments { simple: "databases" } segments { simple: "(default)" } segments { simple: "Main" } segments { simple: "Documents" } segments { simple: "BlueBooks" } segments { simple: "123" } }
疑问:当文档不存在时exists函数不应报错,为何出现该错误?
问题原因与解决方法
核心问题:路径格式与变量使用错误
- Firestore路径格式错误:安全规则中引用文档的标准路径必须以
/databases/$(database)/documents/开头,你写的Main是无效的路径段,应该替换为documents。 - 未使用匹配变量:match规则中定义了
{AppNode}动态变量,但exists路径里硬写了Main,导致规则查找的路径和实际操作的文档路径不匹配,引发服务调用错误。
修正后的规则
match /{AppNode}/Documents/BlueBooks/{bookId} { function isUniqueBlueBook() { // 使用正确的路径格式,并用$(AppNode)匹配动态节点 return !exists(/databases/$(database)/documents/$(AppNode)/Documents/BlueBooks/$(request.resource.id)); } allow create: if isUniqueBlueBook(); }
额外说明
exists函数本身不会因为文档不存在报错,报错的根源是你传入的路径格式不符合Firestore规则要求,或者路径指向的资源结构不存在。- 另外,
create操作的request.resource.id其实就是bookId,也可以直接用$(bookId)代替,代码会更简洁:
return !exists(/databases/$(database)/documents/$(AppNode)/Documents/BlueBooks/$(bookId));
内容的提问来源于stack exchange,提问作者dsl400
相关产品推荐
相关产品推荐

