Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

構建 Cloud Firestore 安全規則

透過集合功能整理內容 你可以依據偏好儲存及分類內容。

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變量將解析為城市文檔名稱,例如SFNYC

粒度操作

在某些情況下, write read為更細粒度的操作很有用。例如,您的應用程序可能希望對文檔創建和刪除文檔強制執行不同的條件。或者您可能希望允許讀取單個文檔但拒絕大型查詢。

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

但是請注意,遞歸通配符的行為取決於規則版本。

版本 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>;
    }
  }
}

每個 match 語句最多可以有一個遞歸通配符,但在版本 2 中,您可以將此通配符放在 match 語句中的任何位置。例如:

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()調用的最大數量
  • 10 用於單文檔請求和查詢請求。
  • 20 用於多文檔讀取、事務和批量寫入。之前的 10 個限制也適用於每個操作。

    例如,假設您創建了一個包含 3 個寫入操作的批處理寫入請求,並且您的安全規則使用 2 個文檔訪問調用來驗證每個寫入。在這種情況下,每個寫入使用其 10 個訪問調用中的 2 個,而批量寫入請求使用其 20 個訪問調用中的 6 個。

超過任一限制都會導致權限被拒絕錯誤。

某些文檔訪問調用可能會被緩存,並且緩存的調用不計入限制。

最大嵌套match語句深度10
一組嵌套match語句中允許的最大路徑長度(以路徑段為單位) 100
一組嵌套match語句中允許的最大路徑捕獲變量數20
最大函數調用深度20
函數參數的最大數量7
每個函數的最大let變量綁定數10
遞歸或循環函數調用的最大數量0(不允許)
每個請求評估的最大表達式數1,000
規則集的最大大小規則集必須遵守兩個大小限制:
  • 從 Firebase 控制台或使用firebase deploy從 CLI 發布的規則集文本源的大小限制為 256 KB。
  • 當 Firebase 處理源並使其在後端處於活動狀態時,編譯規則集的大小限制為 250 KB。

下一步