You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 12:25:03