Firestore安全规则:exists()内联生效但函数调用失效问题排查
Firestore安全规则函数式写法失效问题排查
问题场景
内联写法的规则可正常通过权限校验:
allow get: if exists(/databases/$(database)/documents/rbac/$(org)/users/$(request.auth.uid)); }``` 但将校验逻辑移入函数后,使用AngularFire读取文档时触发权限错误: ```rules_version = '2'; service cloud.firestore { function isUser(uid) { return request.auth.uid == uid; } function isOrgAdmin(org) { return exists(/databases/$(database)/documents/rbac/$(org)/admins/$(request.auth.uid)); } match /databases/{database}/documents { match /users/{uid} { allow get: if isUser(uid); } match /orgs/{org} { allow get: if isOrgAdmin(org); } } }``` 报错信息: ```Error getting document: orgs/18237018238blahblahblah FirebaseError: Missing or insufficient permissions.``` ## 错误原因 核心问题是**函数中`database`变量的作用域不匹配**: - 内联写法中,`$(database)`是在`match /databases/{database}/documents`的子匹配块内,能直接获取到路径参数`database`; - 顶层函数`isOrgAdmin`无法访问匹配块中定义的`database`参数,导致`exists`方法解析的文档路径无效,权限校验自然失败。 另外注意:内联写法检查的是`rbac/$(org)/users/$(request.auth.uid)`,但函数中写的是`rbac/$(org)/admins/$(request.auth.uid)`,如果这是笔误,也会导致校验逻辑和预期不符。 ## 修复方案 将`database`作为参数传入函数,确保函数能正确获取路径变量: ```rules_version = '2'; service cloud.firestore { function isUser(uid) { return request.auth.uid == uid; } // 新增database参数 function isOrgAdmin(database, org) { return exists(/databases/$(database)/documents/rbac/$(org)/admins/$(request.auth.uid)); } match /databases/{database}/documents { match /users/{uid} { allow get: if isUser(uid); } match /orgs/{org} { // 调用时传入database参数 allow get: if isOrgAdmin(database, org); } } }``` 如果之前的`users`和`admins`路径是笔误,记得同步修正函数内的文档路径,保证和业务逻辑一致。 内容的提问来源于stack exchange,提问作者gusgonnet
相关产品推荐
相关产品推荐

