Check out what’s new from Firebase@ Google I/O 2021, and join our alpha program for early access to the new Remote Config personalization feature. Learn more

安全規則語言

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

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

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

基本結構

雲防火牆

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>>
  }
}

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

  • 請求:allow語句中調用的一個或多個方法。這些是您允許運行的方法。標準方法是: getlistcreateupdatedelete 。的readwrite方便的方法使指定的數據庫或存儲路徑上廣泛的讀取和寫入訪問。
  • 路徑:數據庫或存儲位置,表示為 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>>
  }
}

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

  • 請求:allow語句中調用的一個或多個方法。這些是您允許運行的方法。標準方法是: getlistcreateupdatedelete 。的readwrite方便的方法使指定的數據庫或存儲路徑上廣泛的讀取和寫入訪問。
  • 路徑:數據庫或存儲位置,表示為 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規則充當基於傳入或現有數據的二次驗證授予訪問權限。
  • 條件:如果評估為真則允許請求的條件。

規則結構

雲防火牆

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

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

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

語法版本

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

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

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

服務

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

雲防火牆

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塊聲明了一個與請求操作的路徑(傳入的request.path )匹配的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=**} 。該變量可在match語句中作為path對象訪問。

允許

match塊包含一個或多個allow語句。這些是你的實際規則。您可以將allow規則應用於一種或多種方法。對於 Cloud Firestore 或 Cloud Storage, allow語句中的條件必須評估為 true 才能授予任何傳入請求。您還可以編寫不帶條件的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分配如何強制查找 admins 集合。對於不需要不需要查找的惰性求值,請利用&& (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塊, allow語句提供授予請求訪問權限的條件。 requestresource變量可用於規則條件。 Firebase 安全規則語言也支持function聲明。

語法版本

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

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

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

服務

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

雲防火牆

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塊聲明了一個與請求操作的路徑(傳入的request.path )匹配的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=**} 。該變量可在match語句中作為path對象訪問。

允許

match塊包含一個或多個allow語句。這些是你的實際規則。您可以將allow規則應用於一種或多種方法。對於 Cloud Firestore 或 Cloud Storage, allow語句上的條件必須評估為 true 才能授予任何傳入請求。您還可以編寫不帶條件的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分配如何強制查找 admins 集合。對於不需要不需要查找的惰性求值,利用&& (AND) 和||的短路特性(OR) 比較,僅當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規則。

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

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

建築條件

雲防火牆

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

request變量

request變量包括以下字段和對應信息:

request.auth

包含來自 Firebase 身份驗證的身份驗證憑據的 JSON 網絡令牌 (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 網絡令牌 (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.表達式在實時數據庫規則中可用。

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

運營商

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

創造條件

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

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