Firestore安全规则问题:如何仅允许用户创建ID匹配自身UID的文档
问题:限制Firestore用户账户文档创建权限,仅允许用户创建与自身UID匹配的文档
我需要限制userAccounts集合的文档创建权限,要求仅已认证用户能创建文档,且文档ID必须和登录用户的UID一致。之前找到过2019年的相关方案,但都无效。
尝试过的规则版本
第一种规则
match /userAccounts/{userId} { allow create: if request.auth.uid == userId; allow create: if request.auth.uid == request.resource.id; allow create: if path("/databases/$(database)/documents/userAccounts/" + request.auth.uid) == request.path; }
第二种规则
match /userAccounts/{document=**} { allow create: if request.auth.uid == userId; allow create: if request.auth.uid == request.resource.id; allow create: if path("/databases/$(database)/documents/userAccounts/" + request.auth.uid) == request.path; }
我逐个测试了这些规则,组合使用也无效。自2019年以来,规则引擎是否发生了变化导致该需求无法实现?
编辑1:当前规则与测试代码
当前使用的规则
match /userAccounts/{userId}/{documents=**} { allow read, update: if request.auth != null && request.auth.uid == resource.data.userId; allow create: if request.auth != null && request.auth.uid == userId; }
Jest单元测试代码
currentUser = testEnv.authenticatedContext('testUserId123'); it('only current user can CREATE userAccount for current user', async () => { const createByUser = currentUser .firestore() .collection('userAccounts') .add({ userId: 'testUserId123', displayName: 'test name' }); await assertSucceeds(createByUser); });
请问如何编写规则,以仅允许当前用户创建ID与自身auth.uid匹配的文档?
解决方案
问题根源
你的测试代码用了.add()方法,这个方法会自动生成随机文档ID,完全不符合规则里要求的“文档ID等于用户UID”的条件,所以规则验证必然失败。规则引擎并没有变化,核心逻辑依然是验证文档ID和用户UID的一致性。
正确的安全规则
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /userAccounts/{userId} { // 仅允许已认证用户创建ID与自身UID一致的文档 allow create: if request.auth != null && request.auth.uid == userId; // 允许用户读写自己的文档 allow read, update: if request.auth != null && request.auth.uid == userId; } } }
修正后的测试代码
必须用.doc(uid).set()明确指定文档ID为用户UID,而不是用自动生成ID的.add():
currentUser = testEnv.authenticatedContext('testUserId123'); it('only current user can CREATE userAccount for current user', async () => { const createByUser = currentUser .firestore() .collection('userAccounts') .doc('testUserId123') // 强制指定文档ID为用户UID .set({ userId: 'testUserId123', displayName: 'test name' }); await assertSucceeds(createByUser); });
关键说明
如果你的业务逻辑必须使用.add()生成随机ID,那“文档ID与用户UID匹配”的需求本身就无法实现,因为.add()的设计就是生成不可预测的随机ID。只有当你主动将文档ID设置为用户UID时,规则才能生效。
内容的提问来源于stack exchange,提问作者J King
相关产品推荐
相关产品推荐

