Firebase Cloud Firestore安全规则:arrayUnion值唯一性与长度校验
解决Firestore安全规则的两个核心校验需求
针对你当前的events结构(一个包含多个eventID键、每个键对应字符串数组的Map),结合你用arrayUnion更新单个event数组的场景,我们可以通过以下安全规则实现两个核心校验要求:
match /databases/{database}/documents { match /collection/{documentID} { allow write: if // 基础校验:请求数据为Map且仅更新单个字段 request.resource.data is map && request.writeFields.size() == 1 && // 确保更新目标是events下的某个eventID子字段 request.writeFields[0].matches('events\\..+') && // 提取当前更新的eventID let updatedEventId = split(request.writeFields[0], '.')[1] && // 校验该eventID已存在于原文档的events中(可选,根据业务需求调整) updatedEventId in resource.data.events.keys() && // 获取原数组与更新后的新数组 let originalArray = resource.data.events[updatedEventId] && let newArray = request.resource.data[request.writeFields[0]] && // 计算出本次要添加的新value(利用数组差集,arrayUnion特性确保差集仅含一个元素) let newValues = newArray.difference(originalArray) && newValues.size() == 1 && let newValue = newValues[0] && // 校验1:value长度符合要求(示例为1-100,可根据需求调整) newValue.size() > 0 && newValue.size() < 100 && // 校验2:value在所有event的数组中均不存在 all(eventArray in resource.data.events.values() => !eventArray.contains(newValue)); } }
规则细节解释:
- 字段合法性校验:先确保请求是单字段更新,且目标是
events下的某个eventID,避免非法字段修改。 - 提取更新目标:通过
split函数从更新字段名中解析出对应的eventID,确保操作的是已存在的事件。 - 获取新添加值:利用数组
difference方法,对比新旧数组得到本次要添加的唯一value(arrayUnion会自动过滤已存在值,所以差集长度固定为1)。 - 长度校验:直接检查新value的字符串长度是否符合业务要求,可自由调整上下限。
- 全局唯一性校验:用
all函数遍历所有event数组,确保新value在整个events结构中没有重复。
额外提示:
如果你的业务场景允许一次添加多个value(比如arrayUnion传入数组),需要修改newValues.size()的判断,并遍历newValues中的每个元素分别做长度和唯一性校验;如果文档可能不存在events字段,需要补充resource.data.events exists的判断避免规则报错。
内容的提问来源于stack exchange,提问作者Sergo
相关产品推荐
相关产品推荐

