本指南以建構安全性規則指南為基礎,說明如何為 Cloud Firestore Security Rules 新增條件。如果您不熟悉 Cloud Firestore Security Rules 的基本概念,請參閱入門指南。
Cloud Firestore Security Rules 的主要構成元素是條件。條件是布林運算式,可決定是否允許或拒絕特定作業。使用安全性規則編寫條件,檢查使用者驗證、驗證傳入資料,甚至存取資料庫的其他部分。
AI 輔助功能的 AI 提示
如需 AI 輔助,請將下方提示詞複製到 AI 程式設計代理 (例如 Android Studio 內建 Gemini、Antigravity、Claude Code、Codex 和 Cursor)。您可以自訂提示,並與代理反覆調整。如需詳細安裝資訊,請參閱 Firebase 代理技能。
Help me use Firebase in my app.
1. Make sure that **Firebase agent skills** are installed and updated. For Claude Code, Codex, or Cursor agents, help me install the Firebase plugin. For other agents, run `npx skills add firebase/agent-skills`. Always try to use **Firebase agent skills** for Firebase-related tasks.
2. Help me write, validate, and deploy Firebase Security Rules to protect my app's Firestore data.
驗證
最常見的安全規則模式之一,是根據使用者的驗證狀態控管存取權。舉例來說,您的應用程式可能只允許已登入的使用者寫入資料:
service cloud.firestore { match /databases/{database}/documents { // Allow the user to access documents in the "cities" collection // only if they are authenticated. match /cities/{city} { allow read, write: if request.auth != null; } } }
另一個常見模式是確保使用者只能讀取及寫入自己的資料:
service cloud.firestore { match /databases/{database}/documents { // Make sure the uid of the requesting user matches name of the user // document. The wildcard expression {userId} makes the userId variable // available in rules. match /users/{userId} { allow read, update, delete: if request.auth != null && request.auth.uid == userId; allow create: if request.auth != null; } } }
如果應用程式使用 Firebase 驗證或 Google Cloud Identity Platform,request.auth 變數會包含要求資料的用戶端驗證資訊。如要進一步瞭解 request.auth,請參閱參考文件。
資料驗證
許多應用程式會將存取控管資訊,儲存為資料庫中文件的欄位。Cloud Firestore Security Rules可根據文件資料,動態允許或拒絕存取:
service cloud.firestore { match /databases/{database}/documents { // Allow the user to read data if the document has the 'visibility' // field set to 'public' match /cities/{city} { allow read: if resource.data.visibility == 'public'; } } }
resource 變數是指要求的檔案,resource.data 則是檔案中儲存的所有欄位和值的對應。如要進一步瞭解 resource 變數,請參閱參考文件。
寫入資料時,您可能需要比較傳入資料與現有資料。在這種情況下,如果規則集允許待處理的寫入作業,request.resource 變數就會包含文件的未來狀態。對於僅修改文件欄位子集的 update 作業,request.resource 變數會包含作業後待處理的文件狀態。您可以檢查 request.resource 中的欄位值,避免不必要或不一致的資料更新:
service cloud.firestore { match /databases/{database}/documents { // Make sure all cities have a positive population and // the name is not changed match /cities/{city} { allow update: if request.resource.data.population > 0 && request.resource.data.name == resource.data.name; } } }
存取其他文件
使用 get() 和 exists() 函式,安全性規則可以根據資料庫中的其他文件評估傳入的要求。get() 和 exists() 函式都需要完整指定的文件路徑。使用變數建構 get() 和 exists() 的路徑時,您必須使用 $(variable) 語法明確逸出變數。
在以下範例中,比對陳述式 match /databases/{database}/documents 會擷取 database 變數,並用於形成路徑:
service cloud.firestore { match /databases/{database}/documents { match /cities/{city} { // Make sure a 'users' document exists for the requesting user before // allowing any writes to the 'cities' collection allow create: if request.auth != null && exists(/databases/$(database)/documents/users/$(request.auth.uid)); // Allow the user to delete cities if their user document has the // 'admin' field set to 'true' allow delete: if request.auth != null && get(/databases/$(database)/documents/users/$(request.auth.uid)).data.admin == true; } } }
如果是寫入作業,您可以使用 getAfter() 函式,在交易或批次寫入作業完成後,但在交易或批次提交前,存取文件的狀態。與 get() 相同,getAfter() 函式會採用完整指定的文件路徑。您可以使用 getAfter() 定義一組必須同時執行的寫入作業,做為交易或批次作業。
存取呼叫限制
每次評估規則集時,文件存取呼叫次數有限制:
- 單一文件要求和查詢要求的上限為 10 項。
-
多文件讀取、交易和批次寫入作業則為 20。每項作業也適用先前的 10 個限制。
舉例來說,假設您建立含有 3 項寫入作業的批次寫入要求,且安全性規則使用 2 次文件存取呼叫來驗證每項寫入作業。在這種情況下,每次寫入會使用 10 次存取呼叫中的 2 次,而批次寫入要求會使用 20 次存取呼叫中的 6 次。
如果超過任一上限,就會發生權限遭拒錯誤。部分文件存取呼叫可能會快取,而快取的呼叫不會計入限制。
如要詳細瞭解這些限制對交易和批次寫入的影響,請參閱保護原子作業指南。
存取呼叫和定價
使用這些函式會在資料庫中執行讀取作業,這表示即使規則拒絕要求,您仍須支付讀取文件的費用。如需更具體的帳單資訊,請參閱「規則定價」。
自訂函式
隨著安全性規則變得越來越複雜,您可能需要將一組條件包裝在函式中,以便在規則集中重複使用。安全性規則支援自訂函式。自訂函式的語法與 JavaScript 類似,但安全性規則函式是以特定領域語言編寫,有一些重要限制:
- 函式只能包含一個
return陳述式。不得包含任何其他邏輯。例如,無法執行迴圈或呼叫外部服務。 - 函式可以自動存取定義範圍內的函式和變數。舉例來說,在
service cloud.firestore範圍內定義的函式可以存取resource變數和內建函式,例如get()和exists()。 - 函式可以呼叫其他函式,但不得遞迴。呼叫堆疊總深度上限為 10。
- 在規則版本
v2中,函式可以使用let關鍵字定義變數。函式最多可有 10 個 let 繫結,但必須以回傳敘述結尾。
函式是以 function 關鍵字定義,並接受零或多個引數。舉例來說,您可能想將上述範例中使用的兩種條件合併為單一函式:
service cloud.firestore { match /databases/{database}/documents { // True if the user is signed in or the requested data is 'public' function signedInOrPublic() { return request.auth.uid != null || resource.data.visibility == 'public'; } match /cities/{city} { allow read, write: if signedInOrPublic(); } match /users/{user} { allow read, write: if signedInOrPublic(); } } }
在安全性規則中使用函式,可讓規則在複雜度增加時更容易維護。
規則不是篩選器
保護資料並開始編寫查詢後,請注意,安全性規則並非篩選器。您無法為集合中的所有文件編寫查詢,並預期規則只會傳回目前用戶端有權存取的文件。
舉例來說,請看以下安全性規則:
service cloud.firestore {
match /databases/{database}/documents {
// Allow the user to read data if the document has the 'visibility'
// field set to 'public'
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
}
}
拒絕:這項規則會拒絕下列查詢,因為結果集可能包含 visibility 不是 public 的文件:
網頁
db.collection("cities").get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, " => ", doc.data());
});
});允許:這項規則允許下列查詢,因為 where("visibility", "==", "public") 子句可保證結果集符合規則條件:
網頁
db.collection("cities").where("visibility", "==", "public").get()
.then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
console.log(doc.id, " => ", doc.data());
});
});規則安全性規則會根據潛在結果評估每項查詢,如果查詢可能傳回用戶端無權讀取的文件,則會失敗。查詢必須遵循安全性規則設定的限制。如要進一步瞭解安全性規則和查詢,請參閱「安全查詢資料」。
後續步驟
- 瞭解安全性規則對查詢的影響。
- 瞭解如何建構安全性規則。
- 請參閱安全性規則參考資料。
- 如果應用程式使用 Cloud Storage for Firebase,請參閱這篇文章,瞭解如何編寫存取 Cloud Firestore 文件的 Cloud Storage Security Rules 條件。