如何为Firestore中数组内的Map字段编写安全验证规则?
Firestore数组内Map字段的安全验证方案
核心方案:使用every()方法遍历验证数组元素
Firestore安全规则支持用every()方法对数组的所有元素进行批量验证,不需要提前知晓数组长度,刚好适配你不确定元素数量的场景。
具体规则示例
假设你的目标集合为yourCollection,文档中的数组字段名为docField,可以编写如下规则:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /yourCollection/{doc} { allow write: if // 先确保目标字段是数组类型 request.resource.data.docField is list // 遍历数组每个元素,验证格式合法性 && request.resource.data.docField.every(item => // 元素必须是Map类型 item is map // 验证name字段:字符串且非空 && item.name is string && item.name.size() > 0 // 验证age字段:整数且在合理范围(示例为0-120) && item.age is int && item.age >= 0 && item.age <= 120 // 验证type字段:只能是指定枚举值 && item.type in ['default', 'admin', 'guest'] ); } } }
关键细节说明
every(item => ...)会遍历数组的每一个元素,只有当所有元素都满足括号内的验证条件时,整个表达式才返回true- 可根据实际需求调整验证规则:比如age允许浮点数就改成
item.age is float,type的可选值也可自定义 - 如果数组是可选字段(允许不传入),可以用
request.resource.data.get('docField', []).every(...),通过get()方法设置默认空数组,避免字段不存在时触发报错
优化方案:自定义函数复用验证逻辑
如果需要在多个规则中复用数组元素的验证逻辑,可以把验证逻辑抽成自定义函数,让规则更简洁易维护:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 自定义验证函数 function isValidItem(item) { return item is map && item.name is string && item.name.size() > 0 && item.age is int && item.age >= 0 && item.age <= 120 && item.type in ['default', 'admin', 'guest']; } match /yourCollection/{doc} { allow write: if request.resource.data.docField is list && request.resource.data.docField.every(isValidItem); } } }
这种方案无需将每个Map拆分为子集合文档,既避免了额外的写入开销,又能确保数组内所有元素符合数据格式要求。
内容的提问来源于stack exchange,提问作者popClingwrap
相关产品推荐
相关产品推荐

