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 /cities/SF
或使用通配符指向指定路徑中的任何文檔,如match /cities/{city}
。
在上面的示例中,匹配語句使用{city}
通配符語法。這意味著該規則適用於cities
集合中的任何文檔,例如/cities/SF
或/cities/NYC
。當評估 match 語句中的allow
表達式時, city
變量將解析為城市文檔名稱,例如SF
或NYC
。
細化操作
在某些情況下,將read
和write
為更細粒度的操作很有用。例如,您的應用程序可能希望對文檔創建和文檔刪除執行不同的條件。或者您可能希望允許單個文檔讀取但拒絕大型查詢。
read
規則可以分為get
和list
,而write
規則可以分為create
、 update
和delete
:
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
。
但是請注意,遞歸通配符的行為取決於規則版本。
版本 1
默認情況下,安全規則使用版本 1。在版本 1 中,遞歸通配符匹配一個或多個路徑項。它們不匹配空路徑,因此match /cities/{city}/{document=**}
匹配子集合中的文檔但不匹配cities
集合中的文檔,而match /cities/{document=**}
匹配子集合中的兩個文檔cities
集合和子集合。
遞歸通配符必須出現在匹配語句的末尾。
版本 2
在安全規則的版本 2 中,遞歸通配符匹配零個或多個路徑項。 match/cities/{city}/{document=**}
匹配任何子集合中的文檔以及cities
集合中的文檔。
您必須通過添加rules_version = '2';
在您的安全規則的頂部:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /cities/{city}/{document=**} {
allow read, write: if <condition>;
}
}
}
每個匹配語句最多可以有一個遞歸通配符,但在版本 2 中,您可以將此通配符放在匹配語句中的任何位置。例如:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the songs collection group
match /{path=**}/songs/{song} {
allow read, write: if <condition>;
}
}
}
如果您使用集合組查詢,則必須使用版本 2,請參閱保護集合組查詢。
重疊匹配語句
一個文檔可能匹配多個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;
}
}
}
在上面的示例中,將允許對cities
集合的所有讀寫操作,因為第二條規則始終為true
,即使第一條規則始終為false
。
安全規則限制
在使用安全規則時,請注意以下限制:
限制 | 細節 |
---|---|
每個請求的exists() 、 get() 和getAfter() 調用的最大次數 |
超過任一限制都會導致權限被拒絕錯誤。 某些文檔訪問調用可能會被緩存,緩存的調用不計入限制。 |
最大嵌套match 語句深度 | 10 |
一組嵌套match 語句中允許的最大路徑長度(以路徑段為單位) | 100 |
一組嵌套match 語句中允許的最大路徑捕獲變量數 | 20 |
最大函數調用深度 | 20 |
函數參數的最大數量 | 7 |
每個函數的最大let 變量綁定數 | 10 |
遞歸或循環函數調用的最大次數 | 0(不允許) |
每個請求評估的最大表達式數 | 1,000 |
規則集的最大大小 | 規則集必須遵守兩個大小限制:
|