Firestore安全规则问题:阻止重复域名用户创建失败求助
解决Firestore安全规则阻止重复域名用户创建的问题
首先,咱们拆解下问题核心:你想通过安全规则确保新创建的用户不会使用已存在于domains集合中的域名,但当前规则没生效,大概率是两个关键点没处理对——domains集合的文档结构设计和安全规则中数据引用的正确性。
问题1:domains集合的文档ID与规则逻辑不匹配
你的规则里写的是exists(/databases/$(database)/documents/domains/$(request.resource.data.domain)),这意味着你假设domains集合中,每个域名对应的文档ID就是域名本身(比如@domain1作为文档ID)。但你给出的domains文档结构是:
{ "@domain1": { "uid": "randomUID" } }
如果这个文档的ID不是@domain1(而是随机生成的ID),那规则里的exists检查永远找不到对应的文档,自然不会阻止重复域名的用户创建。
修正方案:
把domains集合的文档ID直接设置为域名值(比如@domain1),文档内容简化为:
{ "uid": "randomUID" }
这样规则里的路径才能正确定位到对应域名的文档。
问题2:安全规则中数据引用的错误
在create操作的规则里,你最初用了resource.data.domain,但resource指的是已经创建后的文档,而create操作时文档还不存在,所以必须用request.resource.data.domain来获取请求中要创建的用户数据里的域名。
你之前尝试的!exists(...)写法本身是对的,但前提是路径要正确(也就是上面说的文档ID要匹配)。
修正后的完整安全规则
service cloud.firestore { match /databases/{database}/documents { match /users/{userId} { allow read: if true; allow create: if !exists(/databases/$(database)/documents/domains/$(request.resource.data.domain)); } } }
额外验证建议
- 手动测试文档结构:在Firestore控制台创建一个
domains文档,ID设为@domain1,内容填{"uid": "testUID"},然后尝试创建一个users文档,domain字段设为@domain1,看是否被规则阻止。如果能成功阻止,说明规则生效了。 - 添加域名格式验证:可以额外加一层判断,确保
domain字段符合格式要求(比如必须以@开头),避免无效数据:allow create: if !exists(/databases/$(database)/documents/domains/$(request.resource.data.domain)) && request.resource.data.domain is string && request.resource.data.domain starts with "@"; - 同步维护
domains集合:记得在创建新用户时,要同时在domains集合中创建对应域名的文档(比如通过Cloud Functions或者客户端逻辑),这样后续的规则检查才能持续生效。
内容的提问来源于stack exchange,提问作者Sayegh
相关产品推荐
相关产品推荐

