如何编写Firestore规则实现共享账号用户的对象访问管控?
问题
我想要创建一个数据库,让多个用户共享同一“账号”但拥有不同权限,这些用户都能访问对应账号下的对象,而非各自拥有独立账号。
数据库结构
Users集合
Users{ uuid1 { uuid: 1234, account: 1 }, uuid2 { uuid: 12345, account: 1 } ... }
注:示例中uuid1为文档ID,对应值1234;uuid2为文档ID,对应值12345
自定义Object集合
Object { uuid1 { Object { id1 {} id2 {} ... } uuid2 {} ... }
文档实际路径示例
- 用户文档:
/Users/IiagiaYij - 对象文档:
/Object/IiagiaYij/Object/LDCK、/Object/IiagiaYij/Object/XY34
当前尝试的规则
rules_version = '2'; function isSignedIn() { return request.auth != null; } service cloud.firestore { match /databases/{database}/documents { function isAdmin(uid) { return uid == "VaFd"; } function getUserData(userID) { return get(/databases/(default)/documents/Users/$(userID)).data; } match /{document=**}/{documentID} { allow read, write: if isSignedIn() && (isAdmin(request.auth.uid) || getUserData(request.auth.uid).account == documentID) } } }
当前规则仅对Users文档生效,对Object文档无效——因为Object文档的ID并非账号ID,且Object文档本身不包含账号ID字段。请问是否可以在不将账号ID添加到对象文档中的情况下编写有效的权限规则?
解决方案
可以实现,核心思路是通过从Object文档路径中提取用户UUID,再关联到该UUID对应的账号ID,验证当前用户的账号是否与路径UUID对应的账号一致。
修改后的规则如下:
rules_version = '2'; function isSignedIn() { return request.auth != null; } service cloud.firestore { match /databases/{database}/documents { function isAdmin(uid) { return uid == "VaFd"; } // 获取当前登录用户的账号ID function getCurrentUserAccount() { return get(/databases/$(database)/documents/Users/$(request.auth.uid)).data.account; } // 根据路径中的用户UUID,获取其对应的账号ID function getAccountFromPathUserUUID(userUUID) { return get(/databases/$(database)/documents/Users/$(userUUID)).data.account; } // 控制Users集合的访问权限:用户仅能访问自己的文档,管理员可访问所有 match /Users/{userID} { allow read, write: if isSignedIn() && (isAdmin(request.auth.uid) || request.auth.uid == userID); } // 控制Object集合的访问权限:验证当前用户账号与路径UUID对应的账号一致 match /Object/{userUUID}/Object/{objectID} { allow read, write: if isSignedIn() && ( isAdmin(request.auth.uid) || getCurrentUserAccount() == getAccountFromPathUserUUID(userUUID) ); } } }
规则说明
- 拆分匹配逻辑:分别针对Users和Object集合编写规则,避免通配符导致的路径识别混乱
- 路径参数提取:从Object文档路径中获取
{userUUID}参数,通过函数关联到Users集合中的账号信息 - 账号一致性校验:对比当前用户的账号ID和路径UUID对应的账号ID,一致则允许访问
- 保留管理员权限:管理员仍拥有所有文档的读写权限
这种方案无需修改Object文档的结构,完全依赖Users集合中的账号关联关系实现权限控制。
内容的提问来源于stack exchange,提问作者Gianluca Bettega
相关产品推荐
相关产品推荐

