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

如何编写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)
      );
    }
  }
}

规则说明

  1. 拆分匹配逻辑:分别针对Users和Object集合编写规则,避免通配符导致的路径识别混乱
  2. 路径参数提取:从Object文档路径中获取{userUUID}参数,通过函数关联到Users集合中的账号信息
  3. 账号一致性校验:对比当前用户的账号ID和路径UUID对应的账号ID,一致则允许访问
  4. 保留管理员权限:管理员仍拥有所有文档的读写权限

这种方案无需修改Object文档的结构,完全依赖Users集合中的账号关联关系实现权限控制。


内容的提问来源于stack exchange,提问作者Gianluca Bettega

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 05:27:52