建立 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

精細化營運

在某些情況下,將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

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

版本1

安全規則預設使用版本 1。在版本 1 中,遞歸通配符會符合一個或多個路徑項。它們不匹配空路徑,因此match /cities/{city}/{document=**}匹配子集合中的文檔,但不匹配cities集合中的文檔,而match /cities/{document=**}匹配子集合中的兩個文檔cities集合和子集合。

遞歸通配符必須出現在符合語句的末尾。

版本2

在安全性規則的版本 2 中,遞歸通配符會符合零個或多個路徑項目。 match/cities/{city}/{document=**}符合任何子集合中的文件以及cities集合中的文件。

您必須透過新增rules_version = '2';來選擇加入版本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()呼叫的最大數量
  • 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。

下一步