Firestore规则配置:如何基于用户对象实现事件文档列表权限控制
Firestore 用户所属事件查询规则问题
问题描述
我的Firestore事件文档结构如下:
{ "name": "Some Event Name", "users" : { "a": { "name": "Some Name" }, "b": { "name": "Some Name" } } }
我需要查询当前用户所属的事件,目前用db.events().order(by: "users.\(userId)")来查询,但对应的安全规则无法生效。我只想让用户查看自己所属的事件,当前规则如下:
match /events/{eventId} { allow list: if isAuthed() && request.auth.uid in resource.data.users; }
已知用用户ID数组存储时规则能正常工作,但我更倾向于用对象映射来存储用户姓名,请问有没有可行的解决办法?
解决方案
1. 调整查询条件
Firestore的列表查询规则要求查询必须能过滤出符合权限的文档,否则规则无法高效验证所有返回结果,会直接拒绝请求。你需要在查询中添加过滤条件,确保只返回包含当前用户ID作为users对象键的文档:
db.events() .whereField("users.\(userId)", exists: true) .order(by: "users.\(userId)")
2. 修正安全规则
针对对象类型的users字段,你需要检查当前用户ID是否是该对象的键(而非数组元素),以下两种方式都可以实现:
方式一:直接检查键存在
match /events/{eventId} { allow list: if isAuthed() && request.auth.uid in resource.data.users; }
这里的in操作符对于Map类型会检查用户ID是否是对象的键,只要users对象包含该键,就会返回true。
方式二:检查字段存在
如果更直观,也可以直接检查users.uid路径是否存在:
match /events/{eventId} { allow list: if isAuthed() && exists(resource.data.users[request.auth.uid]); }
原理说明
当使用对象存储用户信息时,Firestore无法像数组那样直接用in操作符做批量过滤,必须通过明确的字段存在性查询来匹配规则要求。调整后的查询和规则会一一对应,确保只有包含当前用户的事件文档会被返回,同时规则也能正确验证权限。
内容的提问来源于stack exchange,提问作者JoeBayLD
相关产品推荐
相关产品推荐

