Firestore安全规则中如何安全获取自定义角色并返回默认值?
Firestore安全规则嵌套字段安全访问与默认值处理
正确实现安全获取角色列表的函数
Firestore规则的逻辑运算严格要求操作数为布尔值,不能像JavaScript那样通过&&/||短路返回非布尔值。你可以通过两种方式安全获取嵌套字段并返回默认空数组:
方式1:使用get()方法逐层安全获取
get()方法允许你指定字段不存在时的默认值,适合多层嵌套的场景:
function userRoles(ownerId) { // 先获取accessRules,不存在则返回空对象 let accessRules = request.auth.token.get('accessRules', {}); // 获取对应ownerId的条目,不存在则返回空对象 let ownerRoleEntry = accessRules.get(ownerId, {}); // 获取roles字段,不存在则返回空数组 return ownerRoleEntry.get('roles', []); }
方式2:使用三元运算符做逐层判断
如果更倾向于显式的存在性检查,用三元运算符替代逻辑与运算,确保返回值类型统一:
function userRoles(ownerId) { return request.auth.token.accessRules != null && request.auth.token.accessRules[ownerId] != null && request.auth.token.accessRules[ownerId].roles != null ? request.auth.token.accessRules[ownerId].roles : []; }
之前代码的错误原因
- 第一次尝试的错误:直接访问
request.auth.token.accessRules时,如果该字段不存在,规则会直接抛出"Property accessRules is undefined"错误——Firestore规则不允许访问未定义的属性。 - 第二次尝试的错误:
rolesExistsFor(ownerId) && request.auth.token.accessRules[ownerId].roles中,&&右侧返回的是数组类型,而Firestore要求逻辑运算的两边必须都是布尔值,因此触发类型错误。
关于权限拒绝的处理
你提到的"当声明不存在时规则报错并返回access denied"是符合预期的:
- 如果你的规则逻辑依赖
userRoles(ownerId)包含特定权限(比如'editor' in userRoles(ownerId)),当字段不存在时,userRoles返回空数组,权限检查会失败,规则自动返回access denied,和报错的效果一致。 - 如果你不需要在函数中返回默认值,而是希望直接在字段不存在时拒绝访问,也可以简化规则,直接在权限判断中做存在性检查,比如:
allow write: if request.auth.token.accessRules != null && request.auth.token.accessRules[ownerId] != null && 'admin' in request.auth.token.accessRules[ownerId].roles;
这种写法在字段不存在时会直接抛出undefined错误,触发access denied,和你预期的处理方式一致。
内容的提问来源于stack exchange,提问作者vir us
相关产品推荐
相关产品推荐

