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

ภาษากฎความปลอดภัย

กฎความปลอดภัยของ Firebase ใช้ประโยชน์จากภาษาแบบกำหนดเองที่ยืดหยุ่น ทรงพลัง ซึ่งรองรับความซับซ้อนและความละเอียดที่หลากหลาย คุณสามารถกำหนดให้กฎเป็นแบบเฉพาะเจาะจงหรือทั่วไปตามที่เหมาะสมสำหรับแอปของคุณ กฎฐานข้อมูลเรียลไทม์ใช้ไวยากรณ์ที่ดูเหมือน JavaScript ในโครงสร้าง JSON กฎของ Cloud Firestore และ Cloud Storage ใช้ภาษาตาม Common Expression Language (CEL) ซึ่งสร้างขึ้นบน CEL พร้อมคำสั่งจับ match และ allow ที่รองรับการเข้าถึงแบบมีเงื่อนไข

เนื่องจากภาษาเหล่านี้เป็นภาษาที่กำหนดเอง จึงมีช่วงการเรียนรู้ ใช้คู่มือนี้เพื่อทำความเข้าใจภาษาของกฎให้ดียิ่งขึ้นเมื่อคุณเจาะลึกลงไปในกฎที่ซับซ้อนยิ่งขึ้น

เลือกผลิตภัณฑ์เพื่อเรียนรู้เพิ่มเติมเกี่ยวกับกฎของผลิตภัณฑ์

โครงสร้างพื้นฐาน

Cloud Firestore

กฎความปลอดภัยของ Firebase ใน Cloud Firestore และ Cloud Storage ใช้โครงสร้างและไวยากรณ์ต่อไปนี้:

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

แนวคิดหลักต่อไปนี้มีความสำคัญต่อการทำความเข้าใจเมื่อคุณสร้างกฎ:

  • คำขอ: เมธอดหรือเมธอดที่เรียกใช้ในคำสั่ง allow นี่เป็นวิธีที่คุณอนุญาตให้เรียกใช้ วิธีการมาตรฐานคือ: get , list , create , update และ delete วิธีการอำนวยความสะดวก read และ write ทำให้สามารถเข้าถึงการอ่านและเขียนแบบกว้างบนฐานข้อมูลหรือพาธหน่วยเก็บข้อมูลที่ระบุ
  • เส้นทาง: ฐานข้อมูลหรือตำแหน่งที่เก็บ ซึ่งแสดงเป็นเส้นทาง URI
  • กฎ: คำสั่ง allow ซึ่งรวมถึงเงื่อนไขที่อนุญาตการร้องขอหากพบว่าเป็นจริง

แต่ละแนวคิดเหล่านี้มีรายละเอียดเพิ่มเติมด้านล่าง

การจัดเก็บเมฆ

กฎความปลอดภัยของ Firebase ใน Cloud Firestore และ Cloud Storage ใช้โครงสร้างและไวยากรณ์ต่อไปนี้:

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

แนวคิดหลักต่อไปนี้มีความสำคัญต่อการทำความเข้าใจเมื่อคุณสร้างกฎ:

  • คำขอ: เมธอดหรือเมธอดที่เรียกใช้ในคำสั่ง allow นี่เป็นวิธีที่คุณอนุญาตให้เรียกใช้ วิธีการมาตรฐานคือ: get , list , create , update และ delete วิธีการอำนวยความสะดวก read และ write ทำให้สามารถเข้าถึงการอ่านและเขียนแบบกว้างบนฐานข้อมูลหรือพาธหน่วยเก็บข้อมูลที่ระบุ
  • เส้นทาง: ฐานข้อมูลหรือตำแหน่งที่เก็บ ซึ่งแสดงเป็นเส้นทาง URI
  • กฎ: คำสั่ง allow ซึ่งรวมถึงเงื่อนไขที่อนุญาตการร้องขอหากพบว่าเป็นจริง

แต่ละแนวคิดเหล่านี้มีรายละเอียดเพิ่มเติมด้านล่าง

ฐานข้อมูลเรียลไทม์

ในฐานข้อมูลเรียลไทม์ กฎความปลอดภัยของ Firebase ประกอบด้วยนิพจน์คล้าย JavaScript ที่มีอยู่ในเอกสาร JSON

พวกเขาใช้ไวยากรณ์ต่อไปนี้:

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

มีสามองค์ประกอบพื้นฐานในกฎ:

  • เส้นทาง: ตำแหน่งฐานข้อมูล สิ่งนี้สะท้อนโครงสร้าง JSON ของฐานข้อมูลของคุณ
  • คำขอ: นี่คือวิธีการที่กฎใช้ในการให้สิทธิ์การเข้าถึง กฎ read และ write ให้สิทธิ์การเข้าถึงแบบอ่านและเขียนแบบกว้าง ในขณะที่กฎ validate ความถูกต้องทำหน้าที่เป็นการตรวจสอบสำรองเพื่อให้สิทธิ์การเข้าถึงตามข้อมูลขาเข้าหรือที่มีอยู่
  • เงื่อนไข: เงื่อนไขที่อนุญาตคำขอหากประเมินเป็นจริง

การสร้างกฎ

Cloud Firestore

องค์ประกอบพื้นฐานของกฎใน Cloud Firestore และ Cloud Storage มีดังนี้:

  • การประกาศ service : ประกาศผลิตภัณฑ์ Firebase ที่กฎมีผล
  • บล็อก match : กำหนดเส้นทางในฐานข้อมูลหรือที่เก็บข้อมูลที่กฎใช้
  • คำสั่ง allow : ให้เงื่อนไขสำหรับการให้สิทธิ์การเข้าถึงโดยแยกตามวิธีการ วิธีการที่รองรับ ได้แก่ get list create update delete และวิธีการอำนวยความสะดวกใน read และ write
  • การประกาศ function เพิ่มเติม: ให้ความสามารถในการรวมและรวมเงื่อนไขเพื่อใช้ในหลายๆ กฎ

service ประกอบด้วยหนึ่งบล็อกหรือมากกว่า match คำสั่ง allow ที่ให้เงื่อนไขการเข้าถึงคำขอ ตัวแปร request และ resource พร้อมใช้งานสำหรับใช้ในเงื่อนไขของกฎ ภาษากฎความปลอดภัยของ Firebase ยังรองรับการประกาศ function อีกด้วย

เวอร์ชันไวยากรณ์

คำสั่ง syntax ระบุเวอร์ชันของภาษากฎ Firebase ที่ใช้ในการเขียนต้นฉบับ เวอร์ชันล่าสุดของภาษาคือ v2

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

ถ้าไม่ได้ระบุคำสั่ง rules_version กฎของคุณจะได้รับการประเมินโดยใช้เครื่องมือ v1

บริการ

การประกาศ service จะกำหนดผลิตภัณฑ์หรือบริการของ Firebase ที่กฎของคุณมีผล คุณสามารถรวมการประกาศ service ได้เพียงรายการเดียวต่อไฟล์ต้นทาง

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

หากคุณกำหนดกฎสำหรับทั้ง Cloud Firestore และ Cloud Storage โดยใช้ Firebase CLI คุณจะต้องรักษากฎเหล่านั้นในไฟล์แยกกัน

จับคู่

บล็อก 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=**} ตัวแปรนี้สามารถเข้าถึงได้ภายในคำสั่ง match เป็นวัตถุ path

อนุญาต

บล็อก match ประกอบด้วยคำสั่ง allow ตั้งแต่หนึ่งคำสั่งขึ้นไป นี่คือกฎที่แท้จริงของคุณ คุณสามารถใช้กฎ allow กับเมธอดอย่างน้อยหนึ่งเมธอด เงื่อนไขในคำสั่ง allow ต้องประเมินเป็นจริงสำหรับ 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()
  • ฟังก์ชันอาจเรียกใช้ฟังก์ชันอื่นแต่ไม่สามารถเรียกซ้ำได้ ความลึกของ call stack ทั้งหมดจำกัดอยู่ที่ 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();
    }
  }
}

นี่คือตัวอย่างที่แสดงอาร์กิวเมนต์ของฟังก์ชันและการมอบหมายงาน คำสั่งการมอบหมายงานให้ต้องคั่นด้วยเครื่องหมายอัฒภาค

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 : ให้เงื่อนไขสำหรับการให้สิทธิ์การเข้าถึงโดยแยกตามวิธีการ วิธีการที่รองรับ ได้แก่ get list create update delete และวิธีการอำนวยความสะดวกใน read และ write
  • การประกาศ function เพิ่มเติม: ให้ความสามารถในการรวมและรวมเงื่อนไขเพื่อใช้ในหลายๆ กฎ

service ประกอบด้วยหนึ่งบล็อกหรือมากกว่า match คำสั่ง allow ที่ให้เงื่อนไขการเข้าถึงคำขอ ตัวแปร request และ resource พร้อมใช้งานสำหรับใช้ในเงื่อนไขของกฎ ภาษากฎความปลอดภัยของ Firebase ยังรองรับการประกาศ function อีกด้วย

เวอร์ชันไวยากรณ์

คำสั่ง syntax ระบุเวอร์ชันของภาษากฎ Firebase ที่ใช้ในการเขียนต้นฉบับ เวอร์ชันล่าสุดของภาษาคือ v2

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

ถ้าไม่ได้ระบุคำสั่ง rules_version กฎของคุณจะได้รับการประเมินโดยใช้เครื่องมือ v1

บริการ

การประกาศ service จะกำหนดผลิตภัณฑ์หรือบริการของ Firebase ที่กฎของคุณมีผล คุณสามารถรวมการประกาศ service ได้เพียงรายการเดียวต่อไฟล์ต้นทาง

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

หากคุณกำหนดกฎสำหรับทั้ง Cloud Firestore และ Cloud Storage โดยใช้ Firebase CLI คุณจะต้องรักษากฎเหล่านั้นในไฟล์แยกกัน

จับคู่

บล็อก 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=**} ตัวแปรนี้สามารถเข้าถึงได้ภายในคำสั่ง match เป็นวัตถุ path

อนุญาต

บล็อก match ประกอบด้วยคำสั่ง allow ตั้งแต่หนึ่งคำสั่งขึ้นไป นี่คือกฎที่แท้จริงของคุณ คุณสามารถใช้กฎ allow กับเมธอดอย่างน้อยหนึ่งเมธอด เงื่อนไขในคำสั่ง allow ต้องประเมินเป็นจริงสำหรับ 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()
  • ฟังก์ชันอาจเรียกใช้ฟังก์ชันอื่นแต่ไม่สามารถเรียกซ้ำได้ ความลึกของ call stack ทั้งหมดจำกัดอยู่ที่ 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();
    }
  }
}

นี่คือตัวอย่างที่แสดงอาร์กิวเมนต์ของฟังก์ชันและการมอบหมายงาน คำสั่งการมอบหมายงานให้ต้องคั่นด้วยเครื่องหมายอัฒภาค

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

วิธี

ใน Realtime Database มีกฎสามประเภท กฎสองประเภทเหล่านี้ — read และ write — ใช้กับวิธีการของคำขอที่เข้ามา ประเภทกฎ validate ใช้โครงสร้างข้อมูลและตรวจสอบความถูกต้องของรูปแบบและเนื้อหาของข้อมูล กฎเรียกใช้ .validate หลังจากตรวจสอบว่ากฎ .write ให้สิทธิ์การเข้าถึง

ประเภทกฎ
.อ่าน อธิบายว่าผู้ใช้สามารถอ่านข้อมูลได้หรือไม่และเมื่อใด
.เขียน อธิบายว่าอนุญาตให้เขียนข้อมูลได้หรือไม่และเมื่อใด
.ตรวจสอบความถูกต้อง กำหนดค่าที่จัดรูปแบบอย่างถูกต้องจะมีลักษณะอย่างไร ไม่ว่าจะมีแอตทริบิวต์ย่อยและประเภทข้อมูลหรือไม่

ตามค่าเริ่มต้น หากไม่มีกฎอนุญาต การเข้าถึงที่เส้นทางจะถูกปฏิเสธ

สภาพอาคาร

Cloud Firestore

เงื่อนไขคือนิพจน์บูลีนที่กำหนดว่าควรอนุญาตหรือปฏิเสธการดำเนินการเฉพาะ ตัวแปร request และ resource จัดเตรียมบริบทสำหรับเงื่อนไขเหล่านั้น

ตัวแปร request

ตัวแปร request ประกอบด้วยฟิลด์ต่อไปนี้และข้อมูลที่สอดคล้องกัน:

request.auth

JSON Web Token (JWT) ที่มีข้อมูลรับรองการตรวจสอบสิทธิ์จาก Firebase Authentication โทเค็น auth รับรองความถูกต้องมีชุดของการอ้างสิทธิ์มาตรฐานและการอ้างสิทธิ์แบบกำหนดเองใดๆ ที่คุณสร้างขึ้นผ่านการตรวจสอบสิทธิ์ของ Firebase เรียนรู้เพิ่มเติมเกี่ยวกับ กฎความปลอดภัยของ Firebase และการตรวจสอบสิทธิ์

request.method

request.method อาจเป็นวิธีมาตรฐานหรือวิธีกำหนดเองก็ได้ วิธีการ read และ write ที่สะดวกยังมีอยู่เพื่อลดความซับซ้อนของกฎการเขียนที่ใช้กับวิธีมาตรฐานแบบอ่านอย่างเดียวหรือเขียนอย่างเดียวทั้งหมดตามลำดับ

request.params

request.params รวมข้อมูลใดๆ ที่ไม่เกี่ยวข้องโดยเฉพาะกับ request.resource ที่อาจเป็นประโยชน์สำหรับการประเมิน ในทางปฏิบัติ แผนที่นี้ควรว่างเปล่าสำหรับวิธีการมาตรฐานทั้งหมด และควรมีข้อมูลที่ไม่ใช่ทรัพยากรสำหรับวิธีการแบบกำหนดเอง บริการจะต้องระมัดระวังที่จะไม่เปลี่ยนชื่อหรือแก้ไขประเภทของคีย์และค่าใดๆ ที่แสดงเป็นพารามิเตอร์

request.path

request.path เป็นเส้นทางสำหรับ resource เป้าหมาย เส้นทางสัมพันธ์กับบริการ ส่วนเส้นทางที่มีอักขระที่ปลอดภัยที่ไม่ใช่ URL เช่น / ถูกเข้ารหัส URL

ตัวแปร resource

resource คือค่าปัจจุบันภายในบริการที่แสดงเป็นแผนผังของคู่คีย์-ค่า การอ้างอิง resource ภายในเงื่อนไขจะทำให้อ่านค่าจากบริการได้มากที่สุดหนึ่งครั้ง การค้นหานี้จะนับรวมกับโควต้าที่เกี่ยวข้องกับบริการสำหรับทรัพยากร สำหรับคำ get resource จะนับรวมในโควต้าเมื่อปฏิเสธเท่านั้น

ตัวดำเนินการและลำดับความสำคัญของตัวดำเนินการ

ใช้ตารางด้านล่างเป็นข้อมูลอ้างอิงสำหรับตัวดำเนินการและลำดับความสำคัญที่เกี่ยวข้องในกฎสำหรับ Cloud Firestore และ Cloud Storage

กำหนดนิพจน์โดยพลการ a และ b ฟิลด์ 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 การแสดงออกที่ประกอบไปด้วย ซ้ายไปขวา

การจัดเก็บเมฆ

เงื่อนไขคือนิพจน์บูลีนที่กำหนดว่าควรอนุญาตหรือปฏิเสธการดำเนินการเฉพาะ ตัวแปร request และ resource จัดเตรียมบริบทสำหรับเงื่อนไขเหล่านั้น

ตัวแปร request

ตัวแปร request ประกอบด้วยฟิลด์ต่อไปนี้และข้อมูลที่สอดคล้องกัน:

request.auth

JSON Web Token (JWT) ที่มีข้อมูลรับรองการตรวจสอบสิทธิ์จาก Firebase Authentication โทเค็น auth รับรองความถูกต้องมีชุดของการอ้างสิทธิ์มาตรฐานและการอ้างสิทธิ์แบบกำหนดเองใดๆ ที่คุณสร้างขึ้นผ่านการตรวจสอบสิทธิ์ของ Firebase เรียนรู้เพิ่มเติมเกี่ยวกับ กฎความปลอดภัยของ Firebase และการตรวจสอบสิทธิ์

request.method

request.method อาจเป็นวิธีมาตรฐานหรือวิธีกำหนดเองก็ได้ วิธีการ read และ write ที่สะดวกยังมีอยู่เพื่อลดความซับซ้อนของกฎการเขียนที่ใช้กับวิธีมาตรฐานแบบอ่านอย่างเดียวหรือเขียนอย่างเดียวทั้งหมดตามลำดับ

request.params

request.params รวมข้อมูลใดๆ ที่ไม่เกี่ยวข้องโดยเฉพาะกับ request.resource ที่อาจเป็นประโยชน์สำหรับการประเมิน ในทางปฏิบัติ แผนที่นี้ควรว่างเปล่าสำหรับวิธีการมาตรฐานทั้งหมด และควรมีข้อมูลที่ไม่ใช่ทรัพยากรสำหรับวิธีการแบบกำหนดเอง บริการจะต้องระมัดระวังที่จะไม่เปลี่ยนชื่อหรือแก้ไขประเภทของคีย์และค่าใดๆ ที่แสดงเป็นพารามิเตอร์

request.path

request.path เป็นเส้นทางสำหรับ resource เป้าหมาย เส้นทางสัมพันธ์กับบริการ ส่วนเส้นทางที่มีอักขระที่ปลอดภัยที่ไม่ใช่ URL เช่น / ถูกเข้ารหัส URL

ตัวแปร resource

resource คือค่าปัจจุบันภายในบริการที่แสดงเป็นแผนผังของคู่คีย์-ค่า การอ้างอิง resource ภายในเงื่อนไขจะทำให้อ่านค่าจากบริการได้มากที่สุดหนึ่งครั้ง การค้นหานี้จะนับรวมกับโควต้าที่เกี่ยวข้องกับบริการสำหรับทรัพยากร สำหรับคำ get resource จะนับรวมในโควต้าเมื่อปฏิเสธเท่านั้น

ตัวดำเนินการและลำดับความสำคัญของตัวดำเนินการ

ใช้ตารางด้านล่างเป็นข้อมูลอ้างอิงสำหรับตัวดำเนินการและลำดับความสำคัญที่เกี่ยวข้องในกฎสำหรับ Cloud Firestore และ Cloud Storage

กำหนดนิพจน์โดยพลการ a และ b ฟิลด์ 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 การแสดงออกที่ประกอบไปด้วย ซ้ายไปขวา

ฐานข้อมูลเรียลไทม์

เงื่อนไขคือนิพจน์บูลีนที่กำหนดว่าควรอนุญาตหรือปฏิเสธการดำเนินการเฉพาะ คุณสามารถกำหนดเงื่อนไขเหล่านั้นใน Realtime Database Rules ได้ด้วยวิธีต่อไปนี้

ตัวแปรที่กำหนดไว้ล่วงหน้า

มีตัวแปรที่กำหนดไว้ล่วงหน้าที่เป็นประโยชน์จำนวนมากซึ่งสามารถเข้าถึงได้ภายในคำจำกัดความของกฎ นี่คือบทสรุปสั้น ๆ ของแต่ละ:

ตัวแปรที่กำหนดไว้ล่วงหน้า
ตอนนี้ เวลาปัจจุบันเป็นมิลลิวินาทีตั้งแต่ยุค Linux ซึ่งใช้งานได้ดีเป็นพิเศษสำหรับการตรวจสอบการประทับเวลาที่สร้างด้วย firebase.database.ServerValue.TIMESTAMP ของ SDK
ราก RuleDataSnapshot ที่แสดงเส้นทางรูทในฐานข้อมูล Firebase ตามที่มีอยู่ก่อนที่จะพยายามดำเนินการ
ข้อมูลใหม่ RuleDataSnapshot ที่แสดงข้อมูลตามที่จะมีอยู่หลังจากการพยายามดำเนินการ ซึ่งรวมถึงข้อมูลใหม่ที่กำลังเขียนและข้อมูลที่มีอยู่
ข้อมูล RuleDataSnapshot ที่แสดงข้อมูลตามที่มีอยู่ก่อนการดำเนินการที่พยายาม
$ ตัวแปร เส้นทางตัวแทนที่ใช้เพื่อแสดงรหัสและคีย์ลูกแบบไดนามิก
รับรองความถูกต้อง แสดงเพย์โหลดโทเค็นของผู้ใช้ที่ผ่านการรับรองความถูกต้อง

ตัวแปรเหล่านี้สามารถใช้ได้ทุกที่ในกฎของคุณ ตัวอย่างเช่น กฎความปลอดภัยด้านล่างรับรองว่าข้อมูลที่เขียนไปยังโหนด /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"
    }
  }
}

กฎตามข้อมูล

ข้อมูลใดๆ ในฐานข้อมูลของคุณสามารถนำมาใช้ในกฎของคุณได้ เมื่อใช้ตัวแปรที่กำหนดไว้ล่วงหน้า root , data และ newData คุณจะสามารถเข้าถึงพาธใดๆ ก็ได้ตามที่ปรากฏก่อนหรือหลังเหตุการณ์เขียน

ลองพิจารณาตัวอย่างนี้ ซึ่งอนุญาตการดำเนินการเขียนตราบเท่าที่ค่าของโหนด /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

คุณยังสามารถใช้กฎตามคิวรีเพื่อจำกัดจำนวนข้อมูลที่ไคลเอนต์ดาวน์โหลดผ่านการดำเนินการอ่าน

ตัวอย่างเช่น กฎต่อไปนี้จำกัดการเข้าถึงการอ่านเฉพาะผลลัพธ์ 1,000 รายการแรกของข้อความค้นหา โดยเรียงลำดับตามลำดับความสำคัญ:

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
บูลีน เป็นจริงสำหรับการค้นหาที่เรียงลำดับตามคีย์ ลำดับความสำคัญ หรือค่า เป็นอย่างอื่น
สอบถาม.orderByChild สตริง
โมฆะ
ใช้สตริงเพื่อแสดงเส้นทางสัมพัทธ์ไปยังโหนดย่อย ตัวอย่างเช่น query.orderByChild === "address/zip" หากคิวรีไม่ได้เรียงลำดับตามโหนดย่อย ค่านี้จะเป็นค่าว่าง
แบบสอบถาม.startAt
แบบสอบถามสิ้นสุดที่
แบบสอบถามเท่ากับ
สตริง
ตัวเลข
บูลีน
โมฆะ
ดึงขอบเขตของแบบสอบถามที่กำลังดำเนินการ หรือคืนค่า null หากไม่มีชุดขอบเขต
แบบสอบถาม.limitToFirst
แบบสอบถาม.limitToLast
ตัวเลข
โมฆะ
ดึงค่าขีดจำกัดของคิวรีที่กำลังดำเนินการ หรือคืนค่า null หากไม่มีการตั้งค่าขีดจำกัด

ผู้ประกอบการ

กฎฐานข้อมูลเรียลไทม์รองรับ ตัวดำเนินการ จำนวนหนึ่งที่คุณสามารถใช้เพื่อรวมตัวแปรในคำสั่งเงื่อนไข ดูรายชื่อ ตัวดำเนินการทั้งหมดในเอกสารอ้างอิง

การสร้างเงื่อนไข

เงื่อนไขที่แท้จริงของคุณจะแตกต่างกันไปตามการเข้าถึงที่คุณต้องการให้สิทธิ์ กฎจงใจให้ความยืดหยุ่นในระดับมหาศาล ดังนั้นกฎของแอปของคุณจึงอาจเรียบง่ายหรือซับซ้อนตามที่คุณต้องการในท้ายที่สุด

สำหรับคำแนะนำบางประการในการสร้างกฎง่ายๆ ที่พร้อมใช้งานจริง โปรดดู กฎความปลอดภัยพื้นฐาน