Catch up on highlights from Firebase at Google I/O 2023. Learn more

安全規則語言

Firebase 安全規則利用支持各種複雜性和粒度的靈活、強大的自定義語言。您可以根據對您的應用程序的意義使您的規則具體化或通用化。實時數據庫規則使用的語法類似於 JSON 結構中的 JavaScript。 Cloud Firestore 和 Cloud Storage 規則使用基於通用表達語言 (CEL) 的語言,該語言構建於 CEL 之上,具有matchallow語句,支持有條件地授予訪問權限。

但是,由於這些是自定義語言,因此存在學習曲線。當您深入研究更複雜的規則時,使用本指南可以更好地理解規則語言。

選擇一個產品以了解有關其規則的更多信息。

基本結構

雲端 Firestore

Cloud Firestore 和 Cloud Storage 中的 Firebase 安全規則使用以下結構和語法:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

在構建規則時,了解以下關鍵概念很重要:

  • Request:allow語句中調用的一個或多個方法。這些是您允許運行的方法。標準方法是: getlistcreateupdatedeletereadwrite便利方法支持對指定數據庫或存儲路徑進行廣泛的讀取和寫入訪問。
  • 路徑:數據庫或存儲位置,表示為 URI 路徑。
  • 規則: allow語句,其中包含一個條件,如果它的計算結果為真,則允許請求。

下面將更詳細地描述這些概念中的每一個。

雲儲存

Cloud Firestore 和 Cloud Storage 中的 Firebase 安全規則使用以下結構和語法:

service <<name>> {
  // Match the resource path.
  match <<path>> {
    // Allow the request if the following conditions are true.
    allow <<methods>> : if <<condition>>
  }
}

在構建規則時,了解以下關鍵概念很重要:

  • Request:allow語句中調用的一個或多個方法。這些是您允許運行的方法。標準方法是: getlistcreateupdatedeletereadwrite便利方法支持對指定數據庫或存儲路徑進行廣泛的讀取和寫入訪問。
  • 路徑:數據庫或存儲位置,表示為 URI 路徑。
  • 規則: allow語句,其中包含一個條件,如果它的計算結果為真,則允許請求。

下面將更詳細地描述這些概念中的每一個。

實時數據庫

在實時數據庫中,Firebase 安全規則由 JSON 文檔中包含的類似 JavaScript 的表達式組成。

他們使用以下語法:

{
  "rules": {
    "<<path>>": {
    // Allow the request if the condition for each method is true.
      ".read": <<condition>>,
      ".write": <<condition>>,
      ".validate": <<condition>>
    }
  }
}

該規則包含三個基本要素:

  • 路徑:數據庫位置。這反映了數據庫的 JSON 結構。
  • 請求:這些是規則用於授予訪問權限的方法。 readwrite規則授予廣泛的讀取和寫入訪問權限,而validate規則充當輔助驗證以根據傳入或現有數據授予訪問權限。
  • 條件:如果計算結果為真,則允許請求的條件。

規則構造

雲端 Firestore

Cloud Firestore 和 Cloud Storage 中規則的基本元素如下:

  • service聲明:聲明規則適用的 Firebase 產品。
  • match塊:定義規則適用的數據庫或存儲桶中的路徑。
  • allow語句:提供授予訪問權限的條件,以方法區分。支持的方法包括: getlistcreateupdatedelete以及便捷方法readwrite
  • 可選function聲明:提供組合和包裝條件以跨多個規則使用的能力。

service包含一個或多個帶有allow語句的match塊,這些語句提供授予請求訪問權限的條件。 requestresource變量可用於規則條件。 Firebase 安全規則語言還支持function聲明。

語法版本

syntax語句指示用於編寫源代碼的 Firebase 規則語言的版本。該語言的最新版本是v2

rules_version = '2';
service cloud.firestore {
...
}

如果未提供rules_version語句,您的規則將使用v1引擎進行評估。

服務

service聲明定義了您的規則適用於哪個 Firebase 產品或服務。每個源文件只能包含一個service聲明。

雲端 Firestore

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

雲儲存

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

如果您使用 Firebase CLI 為 Cloud Firestore 和 Cloud Storage 定義規則,則必須在單獨的文件中維護它們。

匹配

match塊聲明一個path模式,該模式與請求操作的路徑(傳入的request.path )相匹配。 match的主體必須有一個或多個嵌套的match塊、 allow語句或function聲明。嵌套match塊中的路徑是相對於父match塊中的路徑的。

path模式是一個類似於目錄的名稱,可以包含變量或通配符。 path模式允許單路徑段和多路徑段匹配。 path中綁定的任何變量在match範圍或聲明path的任何嵌套範圍內都是可見的。

path模式的匹配可能是部分的或完整的:

  • 部分匹配: path模式是request.path的前綴匹配。
  • 完全匹配: path模式匹配整個request.path

當進行完全匹配時,將評估塊內的規則。當進行部分匹配時,將測試嵌套match規則以查看是否有任何嵌套path完成匹配。

評估每個完整match中的規則以確定是否允許該請求。如果任何匹配規則授予訪問權限,則請求被允許。如果沒有匹配的規則授予訪問權限,則該請求將被拒絕。

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

如上例所示, path聲明支持以下變量:

  • 單段通配符:通配符變量通過將變量括在花括號中來在路徑中聲明: {variable} 。該變量可以在match語句中作為string
  • 遞歸通配符:遞歸或多段通配符匹配路徑上或路徑下的多個路徑段。此通配符匹配您設置的位置下方的所有路徑。您可以通過在段變量的末尾添加=**字符串來聲明它: {variable=**} 。該變量可以作為path對像在match語句中訪問。

允許

match塊包含一個或多個allow語句。這些是您的實際規則。您可以將allow規則應用於一種或多種方法。 allow語句的條件必須評估為 true,Cloud Firestore 或 Cloud Storage 才能授予任何傳入請求。您還可以編寫不帶條件的allow語句,例如allow read 。但是,如果allow語句不包含條件,它總是允許對該方法的請求。

如果滿足該方法的任何allow規則,則允許該請求。此外,如果更廣泛的規則授予訪問權限,則規則授予訪問權限並忽略可能限制訪問的任何更細化的規則。

考慮以下示例,其中任何用戶都可以讀取或刪除他們自己的任何文件。如果請求寫入的用戶擁有文件並且文件是 PNG,則更細化的規則僅允許寫入。用戶可以刪除子路徑中的任何文件——即使它們不是 PNG——因為之前的規則允許這樣做。

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

方法

每個allow語句都包含一個方法,該方法為同一方法的傳入請求授予訪問權限。

方法請求類型
便捷方法
read任何類型的讀取請求
write任何類型的寫請求
標準方法
get讀取單個文檔或文件的請求
list讀取查詢和集合請求
create編寫新文檔或文件
update寫入現有數據庫文檔或更新文件元數據
delete刪除數據

您不能在同一match塊中重疊讀取方法,也不能在同一path聲明中重疊寫入方法。

例如,以下規則將失敗:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

功能

隨著您的安全規則變得越來越複雜,您可能希望將條件集包裝在可以在您的規則集中重複使用的函數中。安全規則支持自定義函數。自定義函數的語法有點像 JavaScript,但安全規則函數是用具有一些重要限制的特定領域語言編寫的:

  • 函數只能包含一個return語句。它們不能包含任何附加邏輯。例如,它們不能執行循環或調用外部服務。
  • 函數可以從定義它們的範圍內自動訪問函數和變量。例如, service cloud.firestore範圍內定義的函數可以訪問resource變量和內置函數,例如get()exists()
  • 函數可以調用其他函數但不能遞歸。總調用堆棧深度限制為 20。
  • 在規則版本v2中,函數可以使用let關鍵字定義變量。函數最多可以有 10 個 let 綁定,但必須以 return 語句結尾。

函數使用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();
    }
  }
}

這是一個顯示函數參數和 let 賦值的示例。 let 賦值語句必須用分號分隔。

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

請注意isAdmin分配如何強制查找管理員集合。對於不需要不需要的查找的懶惰評估,利用&& (AND) 和||的短路特性(或)僅當isAuthor顯示為真(對於&&比較)或假(對於||比較)時才調用第二個函數的比較。

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

隨著規則復雜性的增加,在安全規則中使用函數可以使它們更易於維護。

雲儲存

Cloud Firestore 和 Cloud Storage 中規則的基本元素如下:

  • service聲明:聲明規則適用的 Firebase 產品。
  • match塊:定義規則適用的數據庫或存儲桶中的路徑。
  • allow語句:提供授予訪問權限的條件,以方法區分。支持的方法包括: getlistcreateupdatedelete以及便捷方法readwrite
  • 可選function聲明:提供組合和包裝條件以跨多個規則使用的能力。

service包含一個或多個帶有allow語句的match塊,這些語句提供授予請求訪問權限的條件。 requestresource變量可用於規則條件。 Firebase 安全規則語言還支持function聲明。

語法版本

syntax語句指示用於編寫源代碼的 Firebase 規則語言的版本。該語言的最新版本是v2

rules_version = '2';
service cloud.firestore {
...
}

如果未提供rules_version語句,您的規則將使用v1引擎進行評估。

服務

service聲明定義了您的規則適用於哪個 Firebase 產品或服務。每個源文件只能包含一個service聲明。

雲端 Firestore

service cloud.firestore {
 // Your 'match' blocks with their corresponding 'allow' statements and
 // optional 'function' declarations are contained here
}

雲儲存

service firebase.storage {
  // Your 'match' blocks with their corresponding 'allow' statements and
  // optional 'function' declarations are contained here
}

如果您使用 Firebase CLI 為 Cloud Firestore 和 Cloud Storage 定義規則,則必須在單獨的文件中維護它們。

匹配

match塊聲明一個path模式,該模式與請求操作的路徑(傳入的request.path )相匹配。 match的主體必須有一個或多個嵌套的match塊、 allow語句或function聲明。嵌套match塊中的路徑是相對於父match塊中的路徑的。

path模式是一個類似於目錄的名稱,可以包含變量或通配符。 path模式允許單路徑段和多路徑段匹配。 path中綁定的任何變量在match範圍或聲明path的任何嵌套範圍內都是可見的。

path模式的匹配可能是部分的或完整的:

  • 部分匹配: path模式是request.path的前綴匹配。
  • 完全匹配: path模式匹配整個request.path

當進行完全匹配時,將評估塊內的規則。當進行部分匹配時,將測試嵌套match規則以查看是否有任何嵌套path完成匹配。

評估每個完整match中的規則以確定是否允許該請求。如果任何匹配規則授予訪問權限,則請求被允許。如果沒有匹配的規則授予訪問權限,則該請求將被拒絕。

// Given request.path == /example/hello/nested/path the following
// declarations indicate whether they are a partial or complete match and
// the value of any variables visible within the scope.
service firebase.storage {
  // Partial match.
  match /example/{singleSegment} {   // `singleSegment` == 'hello'
    allow write;                     // Write rule not evaluated.
    // Complete match.
    match /nested/path {             // `singleSegment` visible in scope.
      allow read;                    // Read rule is evaluated.
    }
  }
  // Complete match.
  match /example/{multiSegment=**} { // `multiSegment` == /hello/nested/path
    allow read;                      // Read rule is evaluated.
  }
}

如上例所示, path聲明支持以下變量:

  • 單段通配符:通配符變量通過將變量括在花括號中來在路徑中聲明: {variable} 。該變量可以在match語句中作為string
  • 遞歸通配符:遞歸或多段通配符匹配路徑上或路徑下的多個路徑段。此通配符匹配您設置的位置下方的所有路徑。您可以通過在段變量的末尾添加=**字符串來聲明它: {variable=**} 。該變量可以作為path對像在match語句中訪問。

允許

match塊包含一個或多個allow語句。這些是您的實際規則。您可以將allow規則應用於一種或多種方法。 allow語句的條件必須評估為 true,Cloud Firestore 或 Cloud Storage 才能授予任何傳入請求。您還可以編寫不帶條件的allow語句,例如allow read 。但是,如果allow語句不包含條件,它總是允許對該方法的請求。

如果滿足該方法的任何allow規則,則允許該請求。此外,如果更廣泛的規則授予訪問權限,則規則授予訪問權限並忽略可能限制訪問的任何更細化的規則。

考慮以下示例,其中任何用戶都可以讀取或刪除他們自己的任何文件。如果請求寫入的用戶擁有文件並且文件是 PNG,則更細化的規則僅允許寫入。用戶可以刪除子路徑中的任何文件——即使它們不是 PNG——因為之前的規則允許這樣做。

service firebase.storage {
  // Allow the requestor to read or delete any resource on a path under the
  // user directory.
  match /users/{userId}/{anyUserFile=**} {
    allow read, delete: if request.auth != null && request.auth.uid == userId;
  }

  // Allow the requestor to create or update their own images.
  // When 'request.method' == 'delete' this rule and the one matching
  // any path under the user directory would both match and the `delete`
  // would be permitted.

  match /users/{userId}/images/{imageId} {
    // Whether to permit the request depends on the logical OR of all
    // matched rules. This means that even if this rule did not explicitly
    // allow the 'delete' the earlier rule would have.
    allow write: if request.auth != null && request.auth.uid == userId && imageId.matches('*.png');
  }
}

方法

每個allow語句都包含一個方法,該方法為同一方法的傳入請求授予訪問權限。

方法請求類型
便捷方法
read任何類型的讀取請求
write任何類型的寫請求
標準方法
get讀取單個文檔或文件的請求
list讀取查詢和集合請求
create編寫新文檔或文件
update寫入現有數據庫文檔或更新文件元數據
delete刪除數據

您不能在同一match塊中重疊讀取方法,也不能在同一path聲明中重疊寫入方法。

例如,以下規則將失敗:

service bad.example {
  match /rules/with/overlapping/methods {
    // This rule allows reads to all authenticated users
    allow read: if request.auth != null;

    match another/subpath {
      // This secondary, more specific read rule causes an error
      allow get: if request.auth != null && request.auth.uid == "me";
      // Overlapping write methods in the same path cause an error as well
      allow write: if request.auth != null;
      allow create: if request.auth != null && request.auth.uid == "me";
    }
  }
}

功能

隨著您的安全規則變得越來越複雜,您可能希望將條件集包裝在可以在您的規則集中重複使用的函數中。安全規則支持自定義函數。自定義函數的語法有點像 JavaScript,但安全規則函數是用具有一些重要限制的特定領域語言編寫的:

  • 函數只能包含一個return語句。它們不能包含任何附加邏輯。例如,它們不能執行循環或調用外部服務。
  • 函數可以從定義它們的範圍內自動訪問函數和變量。例如, service cloud.firestore範圍內定義的函數可以訪問resource變量和內置函數,例如get()exists()
  • 函數可以調用其他函數但不能遞歸。總調用堆棧深度限制為 20。
  • 在規則版本v2中,函數可以使用let關鍵字定義變量。函數最多可以有 10 個 let 綁定,但必須以 return 語句結尾。

函數使用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();
    }
  }
}

這是一個顯示函數參數和 let 賦值的示例。 let 賦值語句必須用分號分隔。

function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  let isAdmin = exists(/databases/$(database)/documents/admins/$(userId));
  return isAuthor || isAdmin;
}

請注意isAdmin分配如何強制查找管理員集合。對於不需要不需要的查找的懶惰評估,利用&& (AND) 和||的短路特性(或)僅當isAuthor顯示為真(對於&&比較)或假(對於||比較)時才調用第二個函數的比較。

function isAdmin(userId) {
  return exists(/databases/$(database)/documents/admins/$(userId));
}
function isAuthorOrAdmin(userId, article) {
  let isAuthor = article.author == userId;
  // `||` is short-circuiting; isAdmin called only if isAuthor == false.
  return isAuthor || isAdmin(userId);
}

隨著規則復雜性的增加,在安全規則中使用函數可以使它們更易於維護。

實時數據庫

如上所述,實時數據庫規則包括三個基本元素:作為數據庫 JSON 結構鏡像的數據庫位置、請求類型和授予訪問權限的條件。

數據庫位置

您的規則結構應遵循您存儲在數據庫中的數據結構。例如,在帶有消息列表的聊天應用程序中,您可能擁有如下所示的數據:

  {
    "messages": {
      "message0": {
        "content": "Hello",
        "timestamp": 1405704370369
      },
      "message1": {
        "content": "Goodbye",
        "timestamp": 1405704395231
      },
      ...
    }
  }

您的規則應該反映該結構。例如:

  {
    "rules": {
      "messages": {
        "$message": {
          // only messages from the last ten minutes can be read
          ".read": "data.child('timestamp').val() > (now - 600000)",

          // new messages must have a string content and a number timestamp
          ".validate": "newData.hasChildren(['content', 'timestamp']) &&
                        newData.child('content').isString() &&
                        newData.child('timestamp').isNumber()"
        }
      }
    }
  }

如上例所示,實時數據庫規則支持$location變量來匹配路徑段。在你的路徑段前面使用$前綴來匹配你的規則到路徑上的任何子節點。

  {
    "rules": {
      "rooms": {
        // This rule applies to any child of /rooms/, the key for each room id
        // is stored inside $room_id variable for reference
        "$room_id": {
          "topic": {
            // The room's topic can be changed if the room id has "public" in it
            ".write": "$room_id.contains('public')"
          }
        }
      }
    }
  }

您還可以將$variable與常量路徑名並行使用。

  {
    "rules": {
      "widget": {
        // a widget can have a title or color attribute
        "title": { ".validate": true },
        "color": { ".validate": true },

        // but no other child paths are allowed
        // in this case, $other means any key excluding "title" and "color"
        "$other": { ".validate": false }
      }
    }
  }

方法

在實時數據庫中,存在三種類型的規則。其中兩種規則類型—— readwrite ——適用於傳入請求的方法。 validate規則類型強制執行數據結構並驗證數據的格式和內容。規則在驗證.write規則授予訪問權限後運行.validate規則。

規則類型
。讀描述是否以及何時允許用戶讀取數據。
。寫描述是否以及何時允許寫入數據。
。證實定義格式正確的值的外觀、它是否具有子屬性以及數據類型。

默認情況下,如果沒有規則允許,則拒絕訪問路徑。

建築條件

雲端 Firestore

條件是一個布爾表達式,用於確定是允許還是拒絕特定操作。 requestresource變量為這些條件提供上下文。

request變量

request變量包含以下字段及對應信息:

request.auth

包含來自 Firebase 身份驗證的身份驗證憑據的 JSON Web 令牌 (JWT)。 auth令牌包含一組標準聲明和您通過 Firebase 身份驗證創建的任何自定義聲明。詳細了解Firebase 安全規則和身份驗證

request.method

request.method可以是任何標準方法或自定義方法。還存在便利方法readwrite以簡化分別適用於所有隻讀或所有隻寫標準方法的寫入規則。

request.params

request.params包括任何與request.resource無關但可能對評估有用的數據。實際上,對於所有標準方法,這個映射應該是空的,並且應該包含自定義方法的非資源數據。服務必須注意不要重命名或修改作為參數顯示的任何鍵和值的類型。

request.path

request.path是目標resource的路徑。路徑是相對於服務的。包含非 url 安全字符(例如/的路徑段是 url 編碼的。

resource變量

resource是服務中的當前值,表示為鍵值對映射。在條件中引用resource將導致最多從服務中讀取一次值。此查找將計入資源的任何與服務相關的配額。對於get請求, resource將僅計入拒絕時的配額。

運算符和運算符優先級

使用下表作為運算符及其在 Cloud Firestore 和 Cloud Storage 規則中的相應優先級的參考。

給定任意表達式ab 、一個字段f和一個索引i

操作員描述結合性
a[i] a() af索引、調用、字段訪問左到右
!a -a一元否定右到左
a/ba%ba*b乘法運算符左到右
a+b ab加法運算符左到右
a>ba>=ba關係運算符左到右
a in b存在於列表或地圖中左到右
a is type類型比較,其中type可以是 bool、int、float、number、string、list、map、timestamp、duration、path 或 latlng左到右
a==ba!=b比較運算符左到右
a && b條件與左到右
a || b條件或左到右
a ? true_value : false_value三元表達式左到右

雲儲存

條件是一個布爾表達式,用於確定是允許還是拒絕特定操作。 requestresource變量為這些條件提供上下文。

request變量

request變量包含以下字段及對應信息:

request.auth

包含來自 Firebase 身份驗證的身份驗證憑據的 JSON Web 令牌 (JWT)。 auth令牌包含一組標準聲明和您通過 Firebase 身份驗證創建的任何自定義聲明。詳細了解Firebase 安全規則和身份驗證

request.method

request.method可以是任何標準方法或自定義方法。還存在便利方法readwrite以簡化分別適用於所有隻讀或所有隻寫標準方法的寫入規則。

request.params

request.params包括任何與request.resource無關但可能對評估有用的數據。實際上,對於所有標準方法,這個映射應該是空的,並且應該包含自定義方法的非資源數據。服務必須注意不要重命名或修改作為參數顯示的任何鍵和值的類型。

request.path

request.path是目標resource的路徑。路徑是相對於服務的。包含非 url 安全字符(例如/的路徑段是 url 編碼的。

resource變量

resource是服務中的當前值,表示為鍵值對映射。在條件中引用resource將導致最多從服務中讀取一次值。此查找將計入資源的任何與服務相關的配額。對於get請求, resource將僅計入拒絕時的配額。

運算符和運算符優先級

使用下表作為運算符及其在 Cloud Firestore 和 Cloud Storage 規則中的相應優先級的參考。

給定任意表達式ab 、一個字段f和一個索引i

操作員描述結合性
a[i] a() af索引、調用、字段訪問左到右
!a -a一元否定右到左
a/ba%ba*b乘法運算符左到右
a+b ab加法運算符左到右
a>ba>=ba關係運算符左到右
a in b存在於列表或地圖中左到右
a is type類型比較,其中type可以是 bool、int、float、number、string、list、map、timestamp、duration、path 或 latlng左到右
a==ba!=b比較運算符左到右
a && b條件與左到右
a || b條件或左到右
a ? true_value : false_value三元表達式左到右

實時數據庫

條件是一個布爾表達式,用於確定是允許還是拒絕特定操作。您可以通過以下方式在實時數據庫規則中定義這些條件。

預定義變量

有許多有用的預定義變量可以在規則定義中訪問。以下是每個的簡要總結:

預定義變量
現在自 Linux 紀元以來的當前時間(以毫秒為單位)。這特別適用於驗證使用 SDK 的 firebase.database.ServerValue.TIMESTAMP 創建的時間戳。
一個RuleDataSnapshot,表示在嘗試操作之前 Firebase 數據庫中的根路徑。
新數據一個RuleDataSnapshot,表示在嘗試操作後將存在的數據。它包括正在寫入的新數據和現有數據。
數據一個RuleDataSnapshot,表示在嘗試操作之前存在的數據。
$變量用於表示 ID 和動態子鍵的通配符路徑。
授權表示經過身份驗證的用戶的令牌負載。

這些變量可以在您的規則中的任何地方使用。例如,下面的安全規則確保寫入/foo/節點的數據必須是小於 100 個字符的字符串:

{
  "rules": {
    "foo": {
      // /foo is readable by the world
      ".read": true,

      // /foo is writable by the world
      ".write": true,

      // data written to /foo must be a string less than 100 characters
      ".validate": "newData.isString() && newData.val().length < 100"
    }
  }
}

基於數據的規則

您數據庫中的任何數據都可以在您的規則中使用。使用預定義變量rootdatanewData ,您可以訪問寫入事件之前或之後存在的任何路徑。

考慮這個例子,它允許寫操作,只要/allow_writes/節點的值為true ,父節點沒有設置readOnly標誌,並且在新寫入的數據中有一個名為foo的子節點:

".write": "root.child('allow_writes').val() === true &&
          !data.parent().child('readOnly').exists() &&
          newData.child('foo').exists()"

基於查詢的規則

雖然您不能將規則用作過濾器,但您可以通過在規則中使用查詢參數來限制對數據子集的訪問。使用query.規則中的表達式以根據查詢參數授予讀取或寫入訪問權限。

例如,以下基於查詢的規則使用基於用戶的安全規則和基於查詢的規則將對baskets集合中數據的訪問限制為僅活動用戶擁有的購物籃:

"baskets": {
  ".read": "auth.uid !== null &&
            query.orderByChild === 'owner' &&
            query.equalTo === auth.uid" // restrict basket access to owner of basket
}

以下查詢(包括規則中的查詢參數)將會成功:

db.ref("baskets").orderByChild("owner")
                 .equalTo(auth.currentUser.uid)
                 .on("value", cb)                 // Would succeed

但是,不包含規則中參數的查詢將失敗並出現PermissionDenied錯誤:

db.ref("baskets").on("value", cb)                 // Would fail with PermissionDenied

您還可以使用基於查詢的規則來限制客戶端通過讀取操作下載的數據量。

例如,以下規則將讀取訪問權限限制為僅按優先級排序的查詢的前 1000 個結果:

messages: {
  ".read": "query.orderByKey &&
            query.limitToFirst <= 1000"
}

// Example queries:

db.ref("messages").on("value", cb)                // Would fail with PermissionDenied

db.ref("messages").limitToFirst(1000)
                  .on("value", cb)                // Would succeed (default order by key)

以下query.表達式在實時數據庫安全規則中可用。

基於查詢的規則表達式
表達類型描述
查詢.orderByKey
查詢.orderByPriority
查詢.orderByValue
布爾值對於按鍵、優先級或值排序的查詢為真。否則為假。
query.orderByChild細繩
無效的
使用字符串表示子節點的相對路徑。例如, query.orderByChild === "address/zip" 。如果查詢未按子節點排序,則此值為空。
查詢.startAt
查詢.endAt
查詢.等於
細繩
數字
布爾值
無效的
檢索執行查詢的邊界,如果沒有邊界集則返回 null。
查詢.limitToFirst
查詢.limitToLast
數字
無效的
檢索執行查詢的限制,如果未設置限制,則返回 null。

運營商

實時數據庫規則支持許多運算符,您可以使用這些運算符在條件語句中組合變量。請參閱參考文檔中的完整運算符列表。

創造條件

您的實際情況將根據您要授予的訪問權限而有所不同。規則有意提供了極大程度的靈活性,因此您的應用程序的規則最終可以根據您的需要變得簡單或複雜。

有關創建簡單的生產就緒規則的一些指南,請參閱基本安全規則