组织安全规则

借助 Cloud Firestore 安全规则,您可以控制对数据库中的文档和集合的访问权限。您可以使用灵活的规则语法创建与任意情况(包括对整个数据库执行的所有写入操作和对特定文档的操作)匹配的规则。

本指南介绍安全规则的基本语法和结构。将此语法与安全规则条件结合使用可创建完整的规则集。

服务和数据库声明

Cloud Firestore 安全规则始终以以下声明开头:

service cloud.firestore {
  match /databases/{database}/documents {
    // ...
  }
}

service cloud.firestore 声明将规则范围限制为 Cloud Firestore,以防止 Cloud Firestore 安全规则与其他产品(例如 Cloud Storage)的规则发生冲突。

match /databases/{database}/documents 声明指定规则应该与项目中的所有 Cloud Firestore 数据库都匹配。目前,每个项目只有一个数据库,名为“(default)”。

基本的读取/写入规则

基本规则由一个 match 语句(指定文档路径)和一个 allow 表达式(详细说明何时允许读取指定的数据)构成:

service cloud.firestore {
  match /databases/{database}/documents {

    // Match any document in the 'cities' collection
    match /cities/{city} {
      allow read: if <condition>;
      allow write: if <condition>;
    }
  }
}

所有 match 语句都应指向文档,而不是集合。Match 语句可以指向特定的文档(如 match /cities/SF),也可以使用通配符指向指定路径下的任意文档(如 match /cities/{city})。

在上面的示例中,match 语句使用了 {city} 通配符语法。这意味着相应规则适用于 cities 集合中的任意文档(例如 /cities/SF/cities/NYC)。在对 match 语句中的 allow 表达式求值时,city 变量将解析为城市文档名称(例如 SFNYC)。

细化的操作

在某些情况下,将 readwrite 细分为更细化的操作很有用。例如,您的应用可能希望对文档创建(而非文档删除)强制执行不同的条件。或者,您可能希望允许单个文档读取,但拒绝大量查询。

read 规则可以细分为 getlist,而 write 规则可以细分为 createupdatedelete

service cloud.firestore {
  match /databases/{database}/documents {
    // A read rule can be divided into get and list rules
    match /cities/{city} {
      // Applies to single document read requests
      allow get: if <condition>;

      // Applies to queries and collection read requests
      allow list: if <condition>;
    }

    // A write rule can be divided into create, update, and delete rules
    match /cities/{city} {
      // Applies to writes to nonexistent documents
      allow create: if <condition>;

      // Applies to writes to existing documents
      allow update: if <condition>;

      // Applies to delete operations
      allow delete: if <condition>;
    }
  }
}

分层数据

Cloud Firestore 中的数据以文档集合的形式出现,每个文档可以通过子集合来扩展这种层次结构。了解安全规则如何与分层数据进行交互是非常重要的。

假设 cities 集合中的每个文档都包含一个 landmarks 子集合。由于安全规则仅适用于匹配的路径,因此在 cities 集合上定义的访问权限控制不适用于 landmarks 子集合。不过,您可以编写显式规则来控制对子集合的访问:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      allow read, write: if <condition>;

        // Explicitly define rules for the 'landmarks' subcollection
        match /landmarks/{landmark} {
          allow read, write: if <condition>;
        }
    }
  }
}

嵌套 match 语句时,内层 match 语句的路径始终是相对于外层 match 语句而言的。因此,以下规则集是等效的:

service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city} {
      match /landmarks/{landmark} {
        allow read, write: if <condition>;
      }
    }
  }
}
service cloud.firestore {
  match /databases/{database}/documents {
    match /cities/{city}/landmarks/{landmark} {
      allow read, write: if <condition>;
    }
  }
}

如果您要将规则应用于任意深度的层次结构,请使用递归通配符语法 {name=**}

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

使用递归通配符语法时,通配符变量将包含整个匹配的路径部分,即使相应文档位于多层嵌套的子集合中也是如此。例如,上面列出的规则将与位于 /cities/SF/landmarks/coit_tower 中的文档匹配,document 变量的值将是 SF/landmarks/coit_tower

递归通配符不能与空路径匹配,因此 match /cities/{city}/{document=**} 将与子集合(而非 cities 集合)中的文档匹配,而 match /cities/{document=**} 将同时与 cities 集合和子集合中的文档匹配。

某个文档可以与多个 match 语句匹配。如果有多个 allow 表达式匹配某个请求,则只要任何一个条件为 true,就允许访问:

service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the 'cities' collection.
    match /cities/{city} {
      allow read, write: if false;
    }

    // Matches any document in the 'cities' collection or subcollections.
    match /cities/{document=**} {
      allow read, write: if true;
    }
  }
}

在上面的示例中,因为第二个规则始终为 true,所以系统允许对 cities 集合进行所有读写操作,即使第一个规则始终为 false 也是如此。

安全规则限制

在处理安全规则时,请注意以下限制:

限制 详细信息
每次评估的唯一 exists()get()getAfter() 调用次数上限

每个调用 3 次,但这些调用的总数上限为 5 次。针对同一文档的多个请求不会计为独立的请求。

在对某个事务或批量写入中的单个或一组写入操作的规则进行评估时,针对写入目标的请求数不会计入此限额。

函数调用深度上限 20
递归或循环函数调用次数上限 0(不允许)
规则集中的表达式数量上限 10000
规则集的大小上限 64 KB

后续步骤

发送以下问题的反馈:

此网页
需要帮助?请访问我们的支持页面