API ของกฎความปลอดภัยของฐานข้อมูล Firebase

กฎ: ประเภท

.read

มอบสิทธิ์เข้าถึงตำแหน่งฐานข้อมูลเรียลไทม์ของ Firebase ระดับอ่านของไคลเอ็นต์

กฎ .read เป็นกฎความปลอดภัยประเภทหนึ่งที่ให้สิทธิ์อ่านตำแหน่งฐานข้อมูลเรียลไทม์ของ Firebase ของไคลเอ็นต์ เช่น

 ".read": "auth != null && auth.provider == 'twitter'"

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

กฎ .read มีสิทธิ์เข้าถึงตัวแปรกฎทั้งหมดของ Firebase Realtime Database ยกเว้น newData

เขียน

ให้สิทธิ์ไคลเอ็นต์เขียนตำแหน่งของฐานข้อมูลเรียลไทม์ของ Firebase

กฎ .write เป็นกฎความปลอดภัยประเภทหนึ่งที่ให้สิทธิ์ไคลเอ็นต์ในการเขียนตำแหน่งของฐานข้อมูลเรียลไทม์ของ Firebase เช่น

".write": "auth != null && auth.token.isAdmin == true"

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

กฎ .write มีสิทธิ์เข้าถึงตัวแปรกฎทั้งหมดของ Firebase Realtime Database

.verifyate

ใช้เมื่อกฎ .write ให้สิทธิ์เข้าถึง เพื่อให้แน่ใจว่าข้อมูลที่เขียนสอดคล้องกับสคีมาเฉพาะ

กฎ .validate จะใช้เมื่อกฎ .write ให้สิทธิ์เข้าถึง เพื่อให้แน่ใจว่าข้อมูลที่เขียนสอดคล้องกับมาตรฐานที่เฉพาะเจาะจง นอกเหนือจากการให้สิทธิ์เข้าถึง .write แล้ว กฎ .validate ที่เกี่ยวข้องทั้งหมดจะต้องสำเร็จก่อนอนุญาตการเขียน เช่น

".validate": "newData.hasChildren(['name', 'age'])"

ค่าของกฎ .validate คือสตริงที่ได้รับการประเมินเป็นชุดย่อยของไวยากรณ์นิพจน์ของ JavaScript โดยมีการเปลี่ยนแปลงลักษณะการทำงานเล็กน้อยเพื่อเพิ่มความชัดเจนและถูกต้อง

กฎ .validate มีสิทธิ์เข้าถึงตัวแปรกฎทั้งหมดของ Firebase Realtime Database

.indexเปิด

ปรับปรุงประสิทธิภาพการค้นหาโดยการบอกฐานข้อมูลเรียลไทม์ของ Firebase ว่าคุณต้องการให้จัดทำดัชนีข้อมูลใด

กฎ .indexOn จะบอกให้เซิร์ฟเวอร์ฐานข้อมูลเรียลไทม์ของ Firebase จัดทำดัชนีคีย์ที่เฉพาะเจาะจงในข้อมูลเพื่อปรับปรุงประสิทธิภาพการค้นหา ตัวอย่างเช่น เมื่อมีฐานข้อมูลที่มีคอลเล็กชันข้อมูลไดโนเสาร์ เราสามารถบอกให้ Firebase Realtime Database ช่วยเพิ่มประสิทธิภาพให้กับการค้นหาก่อนที่ข้อมูลจะแสดงผลจากเซิร์ฟเวอร์โดยการเพิ่มกฎนี้

{
  "rules": {
    "dinosaurs": {
      ".indexOn": ["height", "length"]
    }
  }
}

คุณสามารถดูข้อมูลเพิ่มเติมเกี่ยวกับกฎ .indexOn โดยดูที่ส่วนคู่มือด้านความปลอดภัยเกี่ยวกับการจัดทำดัชนีข้อมูลของคุณ

กฎ: ตัวแปร

การตรวจสอบสิทธิ์

ตัวแปรที่มีเพย์โหลดโทเค็นหากไคลเอ็นต์ได้รับการตรวจสอบแล้ว หรือ null ในกรณีที่ไคลเอ็นต์ไม่ผ่านการตรวจสอบสิทธิ์

ฐานข้อมูลเรียลไทม์ของ Firebase ช่วยให้คุณตรวจสอบสิทธิ์กับผู้ให้บริการหลายรายที่มีในตัวได้อย่างง่ายดาย และจะสร้างโทเค็นการตรวจสอบสิทธิ์ให้กับผู้ให้บริการรายนั้น หลังจากตรวจสอบสิทธิ์ผู้ใช้ด้วยหนึ่งในผู้ให้บริการในตัวแล้ว ตัวแปรการตรวจสอบสิทธิ์จะมีข้อมูลต่อไปนี้

ช่อง คำอธิบาย
provider วิธีการตรวจสอบสิทธิ์ที่ใช้ (เช่น "password", "anonymous", "facebook", "github", "google" หรือ "twitter")
uid รหัสผู้ใช้ที่ไม่ซ้ำซึ่งไม่ซ้ำกันในผู้ให้บริการทั้งหมด
token เนื้อหาของโทเค็นรหัสการตรวจสอบสิทธิ์ Firebase โปรดดู auth.token

ในตัวอย่างนี้ เราอาจมีกฎที่อนุญาตให้ผู้ใช้สร้างความคิดเห็นได้ตราบใดที่ผู้ใช้จัดเก็บรหัสผู้ใช้ไว้กับความคิดเห็น

{
  "rules": {
    ".read": true,
    "$comment": {
      ".write": "!data.exists() && newData.child('user_id').val() == auth.uid"
    }
  }
}

เรายังสามารถสร้างกฎเพื่ออนุญาตให้ผู้ใช้สร้างความคิดเห็นได้ตราบใดที่ผู้ใช้ลงชื่อเข้าใช้ผ่าน Facebook

{
  "rules": {
    ".read": true,
    "$comment": {
      ".write": "!data.exists() && auth.provider == 'facebook'"
    }
  }
}

auth.token

ตัวแปรที่มีเนื้อหาของโทเค็นรหัสการตรวจสอบสิทธิ์ Firebase

โทเค็นมีคีย์ต่อไปนี้บางส่วนหรือทั้งหมด

ช่อง คำอธิบาย
email อีเมลที่เชื่อมโยงกับบัญชี หากมี
email_verified true หากผู้ใช้ยืนยันแล้วว่ามีสิทธิ์เข้าถึงที่อยู่ email ผู้ให้บริการบางรายจะยืนยันอีเมลที่ตนเองเป็นเจ้าของโดยอัตโนมัติ
phone_number หมายเลขโทรศัพท์ที่เชื่อมโยงกับบัญชี หากมี
name ชื่อที่แสดงของผู้ใช้ หากตั้งค่าไว้
sub Firebase UID ของผู้ใช้ ชื่อนี้จะเป็นค่าที่ไม่ซ้ำกันภายในโปรเจ็กต์
firebase.identities พจนานุกรมของข้อมูลประจำตัวทั้งหมดที่เชื่อมโยงกับบัญชีของผู้ใช้นี้ คีย์ของพจนานุกรมสามารถเป็น email, phone, google.com, facebook.com, github.com, twitter.com ค่าของพจนานุกรมคืออาร์เรย์ของตัวระบุที่ไม่ซ้ำกันสำหรับผู้ให้บริการข้อมูลประจำตัวแต่ละรายที่เชื่อมโยงกับบัญชี ตัวอย่างเช่น auth.token.firebase.identities["google.com"][0] จะมีรหัสผู้ใช้ Google รหัสแรกที่เชื่อมโยงกับบัญชี
firebase.sign_in_provider ผู้ให้บริการการลงชื่อเข้าใช้ที่ใช้เพื่อรับโทเค็นนี้ อาจเป็นสตริงใดสตริงหนึ่งต่อไปนี้ custom, password, phone, anonymous, google.com, facebook.com, github.com, twitter.com
firebase.tenant รหัสกลุ่มผู้ใช้ที่เชื่อมโยงกับบัญชี (หากมี) เช่น tenant2-m6tyz

หากใช้การตรวจสอบสิทธิ์ที่กำหนดเอง auth.token จะมีคอลัมน์ที่กำหนดเองด้วย การกล่าวอ้างที่นักพัฒนาซอฟต์แวร์ระบุ

ค่าทั้งหมดนี้สามารถใช้ภายในกฎได้ ตัวอย่างเช่น ในการจำกัดการเข้าถึงบัญชี Google ที่เชื่อมโยงกับที่อยู่ gmail.com เราสามารถเพิ่มกฎดังนี้

{
  "rules": {
    ".read": "auth != null",
    "gmailUsers": {
      "$uid": {
        ".write": "auth.token.email_verified == true && auth.token.email.matches(/.*@gmail.com$/)"
      }
    }
  }
}

เพื่อความครบถ้วน ช่องต่อไปนี้จะรวมอยู่ใน auth.token ด้วย แต่ช่องเหล่านี้อาจไม่มีประโยชน์ต่อกฎ

ช่อง คำอธิบาย
iss ผู้ออกโทเค็น
aud กลุ่มเป้าหมายสำหรับโทเค็น
auth_time เวลาล่าสุดที่ผู้ใช้ตรวจสอบสิทธิ์ด้วยข้อมูลเข้าสู่ระบบโดยใช้อุปกรณ์ที่ได้รับโทเค็น
iat เวลาที่ออกโทเค็น
exp เวลาที่โทเค็นหมดอายุ

$location

ตัวแปรที่ใช้อ้างอิงคีย์ของ $location ที่ใช้ก่อนหน้านี้ในโครงสร้างกฎได้

เมื่อมี $location ในโครงสร้างกฎ คุณจะใช้ตัวแปร $ ที่ตรงกันภายในนิพจน์กฎเพื่อดูชื่อย่อยจริงที่อ่านหรือเขียนได้ ดังนั้นสมมติว่าเราต้องการให้ผู้ใช้ทุกคนอ่านและเขียนตำแหน่ง /users/<user> ของตนเอง เราน่าจะใช้

{
  "rules": {
    "users": {
      "$user": {
        ".read": "auth.uid === $user",
        ".write": "auth.uid === $user"
      }
    }
  }
}

เมื่อไคลเอ็นต์พยายามเข้าถึง /users/barney ตำแหน่งเริ่มต้นของ $user จะจับคู่กับ $user ซึ่งเท่ากับ "barney" ดังนั้นกฎ .read จะตรวจสอบว่า auth.uid === 'barney' หรือไม่ ดังนั้น การอ่าน /users/barney จะสำเร็จก็ต่อเมื่อไคลเอ็นต์ได้รับการตรวจสอบสิทธิ์ด้วย UID ของ "barney"

ตอนนี้

มีจำนวนมิลลิวินาทีนับตั้งแต่ Unix Epoch ตามข้อมูลในเซิร์ฟเวอร์ฐานข้อมูลเรียลไทม์ของ Firebase

ตัวแปร now มีจำนวนมิลลิวินาทีนับตั้งแต่ UNIX Epoch ตามข้อมูลในเซิร์ฟเวอร์ฐานข้อมูลเรียลไทม์ของ Firebase ตัวอย่างเช่น คุณสามารถใช้ค่านี้เพื่อตรวจสอบว่าเวลา created ของผู้ใช้ไม่ได้ตั้งค่าเป็นเวลาในอนาคตหรือไม่

{
  "rules": {
    "users": {
      "$user": {
        "created": {
          ".validate": "newData.val() < now"
        }
      }
    }
  }
}

รูท

RuleDataSnapshot ที่สอดคล้องกับข้อมูลปัจจุบันที่รูทของฐานข้อมูลเรียลไทม์ของ Firebase

ตัวแปรรูทจะให้ RuleDataSnapshot ซึ่งตรงกับข้อมูลปัจจุบันที่รากของฐานข้อมูลเรียลไทม์ของ Firebase ซึ่งคุณสามารถใช้เพื่ออ่านข้อมูลในฐานข้อมูลในนิพจน์กฎได้ ตัวอย่างเช่น หากต้องการอนุญาตให้ผู้ใช้อ่าน /comments เฉพาะในกรณีที่ตั้งค่า /users/<id>/active เป็น "จริง" เราจะใช้สิ่งต่อไปนี้

{
  "rules": {
    "comments": {
      ".read": "root.child('users').child(auth.uid).child('active').val() == true"
    }
  }
}

จากนั้น หาก /users/barney/active มีค่า true แสดงว่าผู้ใช้ตรวจสอบสิทธิ์ด้วย uid ของ "barney" สามารถเขียนไปยังโหนด /comments ได้

ข้อมูล

RuleDataSnapshot ที่สอดคล้องกับข้อมูลปัจจุบันในฐานข้อมูลเรียลไทม์ของ Firebase ที่ตำแหน่งของกฎที่ใช้งานอยู่ในปัจจุบัน

ตัวแปรข้อมูลจะให้ RuleDataSnapshot ซึ่งตรงกับข้อมูลปัจจุบันในตำแหน่งฐานข้อมูลของกฎที่ใช้งานอยู่ในปัจจุบัน (ซึ่งตรงข้ามกับรูท ซึ่งจะให้ข้อมูลรากของฐานข้อมูล)

ดังนั้นหากต้องการให้ลูกค้าเข้าถึง /users/<user> หากตั้งค่า /users/<user>/public เป็น "จริง" ให้ใช้

{
  "rules": {
    "users": {
      "$user": {
        ".read": "data.child('public').val() == true"
      }
    }
  }
}

ตัวแปรข้อมูลใช้ได้ใน .read, .write และ กฎ .validate ข้อ

ข้อมูลใหม่

RuleDataSnapshot ซึ่งตรงกับข้อมูลที่จะแสดงหากอนุญาตให้มีการเขียน

สำหรับกฎ .write และ .validate ตัวแปร newData จะแสดง RuleDataSnapshot ซึ่งสอดคล้องกับข้อมูลที่จะแสดงหากอนุญาตให้มีการเขียน (เป็น "การรวม" ข้อมูลที่มีอยู่เข้ากับข้อมูลใหม่ที่เขียน) ดังนั้นหากคุณต้องการให้แน่ใจว่าผู้ใช้ทุกคนมีชื่อและอายุ คุณสามารถใช้:

{
  "rules": {
    "users": {
      "$user": {
        ".read": true,
        ".write": true,
        ".validate": "newData.hasChildren(['name', 'age'])"
      }
    }
  }
}

เนื่องจาก newData จะรวมข้อมูลที่มีอยู่เข้ากับข้อมูลใหม่ จึงทำงานได้อย่างถูกต้องแม้จะเป็น "บางส่วน" อัปเดต เช่น

var fredRef = firebase.database().ref("users/fred");
// Valid since we have a name and age.
fredRef.set({ name: "Fred", age: 19 });
// Valid since we are updating the name but there's already an age.
fredRef.child("age").set(27);
// Invalid since the .validate rule will no longer be true.
fredRef.child("name").remove();

ตัวแปร newData ไม่พร้อมใช้งานในกฎ .read ข้อเนื่องจากไม่มีการเขียนข้อมูลใหม่ ใช้ data เท่านั้น

RuleDataSnapshot: เมธอด

val()

รับค่าพื้นฐาน (string, number, boolean หรือ null) จาก RuleDataSnapshot นี้

Return Value: (String, Number, Boolean, Null) - ค่าพื้นฐานจาก RuleDataSnapshot นี้

การเรียกใช้ val() ใน RuleDataSnapshot ที่มีข้อมูลย่อยจะไม่แสดงผลออบเจ็กต์ที่มีรายการย่อย ซึ่งต่างจาก DataSnapshot.val() แต่จะแสดงผลค่าคำแนะนําพิเศษแทน การทำเช่นนี้จะช่วยให้กฎทำงานอย่างมีประสิทธิภาพสูงสุดอยู่เสมอ

ดังนั้น คุณจึงต้องใช้ child() เพื่อเข้าถึงรายการย่อยเสมอ (เช่น data.child('name').val() ไม่ใช่ data.val().name)

ตัวอย่างนี้อนุญาตให้อ่านได้ก็ต่อเมื่อตั้งค่าย่อย isReadable เป็น true ในตำแหน่งที่อ่านอยู่

".read": "data.child('isReadable').val() == true"

เด็ก()

รับ RuleDataSnapshot สำหรับตำแหน่งที่เส้นทางแบบสัมพัทธ์ที่ระบุ

อาร์กิวเมนต์: childPath String - เส้นทางแบบสัมพัทธ์ไปยังตำแหน่งของข้อมูลย่อย

ผลลัพธ์: RuleDataSnapshot - RuleDataSnapshot สำหรับสถานที่ตั้งย่อย

เส้นทางแบบสัมพัทธ์อาจเป็นชื่อย่อยแบบง่าย (เช่น "fred") หรือเส้นทางที่คั่นด้วยเครื่องหมายทับในระดับที่ลึกขึ้น (เช่น "fred/name/first") หากตำแหน่งย่อยไม่มีข้อมูล ระบบจะแสดง RuleDataSnapshot ที่ว่างเปล่า

ตัวอย่างนี้อนุญาตให้อ่านได้ก็ต่อเมื่อตั้งค่าย่อย isReadable เป็น true ในตำแหน่งที่อ่านอยู่

".read": "data.child('isReadable').val() == true"

หลัก()

รับ RuleDataSnapshot สำหรับตำแหน่งระดับบนสุด

ผลลัพธ์: RuleDataSnapshot - RuleDataSnapshot สำหรับสถานที่ตั้งระดับบนสุด

หากอินสแตนซ์นี้อ้างถึงรูทของฐานข้อมูลเรียลไทม์ของ Firebase อินสแตนซ์นี้ไม่มีระดับบนสุดและ parent() จะล้มเหลว ทำให้ข้ามนิพจน์กฎปัจจุบัน (เป็นความล้มเหลว)

ตัวอย่างนี้อนุญาตให้อ่านได้เมื่อตั้งค่ารายการย่อย isReadable เป็น "จริง" เท่านั้น

".read": "data.parent().child('isReadable').val() == true"

hasChild(childPath)

แสดงค่า "จริง" หากมีรายการย่อยที่ระบุ

อาร์กิวเมนต์: childPath String - เส้นทางแบบสัมพัทธ์ไปยังตำแหน่งของผู้มีโอกาสเป็นเด็ก

ผลลัพธ์: บูลีน - true หากมีข้อมูลอยู่ที่เส้นทางย่อยที่ระบุ และอีก false

ตัวอย่างนี้อนุญาตให้เขียนข้อมูลได้เมื่อมี "name" ย่อยอยู่เท่านั้น

".validate": "newData.hasChild('name')"

มีเด็ก([เด็ก])

ตรวจหาการมีอยู่ของเด็ก

อาร์กิวเมนต์: children Array ไม่บังคับ - อาร์เรย์ของคีย์ย่อยที่ต้องมีทั้งหมด

ค่าการคืนสินค้า: Boolean - true หากมีรายการย่อย (ระบุ) และอีก false

หากไม่ระบุอาร์กิวเมนต์ ค่าจะแสดงเป็น "จริง" หาก RuleDataSnapshot มีรายการย่อย หากมีการระบุอาร์เรย์ของชื่อย่อย ฟังก์ชันนั้นจะคืนค่าเป็นจริงก็ต่อเมื่อรายการย่อยทั้งหมดที่ระบุใน RuleDataSnapshot

ตัวอย่างนี้อนุญาตให้เขียนข้อมูลได้ต่อเมื่อข้อมูลมีตั้งแต่ 1 รายการขึ้นไปเท่านั้น

".validate": "newData.hasChildren()"

ตัวอย่างนี้อนุญาตให้เขียนข้อมูลได้เมื่อมี "name" เท่านั้น และ "age"

".validate": "newData.hasChildren(['name', 'age'])"

มีอยู่()

แสดงค่า "จริง" หาก RuleDataSnapshot นี้มีข้อมูลอยู่

ผลลัพธ์: Boolean - true หาก RuleDataSnapshot มีข้อมูลอยู่ และอีก false

ฟังก์ชันที่มีอยู่จะแสดงผลเป็น "จริง" หาก RuleDataSnapshot นี้มีข้อมูลอยู่ เป็นฟังก์ชันอำนวยความสะดวกเท่านั้น เนื่องจาก data.exists() เทียบเท่ากับ data.val() != null

ตัวอย่างนี้อนุญาตให้เขียนในตำแหน่งนี้ตราบใดที่ไม่มีข้อมูลอยู่

".write": "!data.exists()"

getPriority()

รับลำดับความสำคัญของข้อมูลใน RuleDataSnapshot

Return Value: (String, Number, Null) - ลำดับความสำคัญของข้อมูลใน RuleDataSnapshot นี้

ตัวอย่างนี้ช่วยให้มั่นใจว่าข้อมูลใหม่ที่เขียนจะมีลำดับความสำคัญ

".validate": "newData.getPriority() != null"

isNumber()

แสดงผลเป็น "จริง" หาก RuleDataSnapshot นี้มีค่าตัวเลข

ผลลัพธ์: Boolean - true หากข้อมูลเป็นตัวเลข และอีก false

ตัวอย่างนี้ดูแลให้ข้อมูลใหม่ที่เขียนมี "age" ระดับล่าง ด้วยค่าที่เป็นตัวเลข

".validate": "newData.child('age').isNumber()"

isString()

แสดงค่า "จริง" หาก RuleDataSnapshot นี้มีค่าสตริง

ค่าการแสดงผล: Boolean - true หากข้อมูลเป็น String อื่นๆ false

ตัวอย่างนี้ดูแลให้ข้อมูลใหม่ที่เขียนมี "name" ย่อย ด้วยค่าสตริง

".validate": "newData.child('name').isString()

isBoolean()

แสดงค่า "จริง" หาก RuleDataSnapshot นี้มีค่าบูลีน

ค่าการแสดงผล: Boolean - true หากข้อมูลเป็น Boolean และอีก false

ตัวอย่างนี้ช่วยให้มั่นใจว่าข้อมูลใหม่ที่เขียนมีระดับย่อยเป็น "ใช้งานอยู่" ด้วยค่าบูลีน

".validate": "newData.child('active').isBoolean()"

สตริง: Properties

ความยาว

แสดงผลความยาวของสตริง

ผลลัพธ์: Number - จำนวนอักขระในสตริง

ตัวอย่างนี้กำหนดให้สตริงต้องมีอักขระอย่างน้อย 10 ตัว

".validate": "newData.isString() && newData.val().length >= 10"

สตริง: เมธอด

มี(สตริงย่อย)

แสดงผลเป็น "จริง" หากสตริงมีสตริงย่อยที่ระบุ

อาร์กิวเมนต์: substring String - สตริงย่อยที่จะค้นหา

ค่าการแสดงผล: Boolean - true หากสตริงมีสตริงย่อยที่ระบุ และอีก false

ตัวอย่างนี้กำหนดให้ข้อมูลเป็นสตริงที่มี "@"

".validate": "newData.isString() && newData.val().contains('@')"

StartWith(สตริงย่อย)

แสดงผลเป็น "จริง" หากสตริงขึ้นต้นด้วยสตริงย่อยที่ระบุ

อาร์กิวเมนต์: substring String - สตริงย่อยที่ต้องมองหาที่จุดเริ่มต้น

ค่าการแสดงผล: Boolean - true หากสตริงมีสตริงย่อยที่ระบุ และอีก false

ตัวอย่างนี้ให้สิทธิ์อ่านหาก auth.token.identifier ขึ้นต้นด้วย "internal-"

".read": "auth.token.identifier.beginsWith('internal-')"

สิ้นสุดด้วย(สตริงย่อย)

แสดงผลเป็น "จริง" หากสตริงลงท้ายด้วยสตริงย่อยที่ระบุ

อาร์กิวเมนต์: substring String - สตริงย่อยที่จะดูในตอนท้าย

ผลลัพธ์: Boolean - true หากสตริงลงท้ายด้วยสตริงย่อยที่ระบุ และอีก false

ตัวอย่างนี้ให้สิทธิ์อ่านหาก auth.token.identifier ลงท้ายด้วย "@company.com"

".read": "auth.token.identifier.endsWith('@company.com')"

แทนที่(สตริงย่อย, การแทนที่)

แสดงผลสำเนาของสตริงที่มีอินสแตนซ์ทั้งหมดของสตริงย่อยที่ระบุซึ่งแทนที่ด้วยสตริงแทนที่ที่ระบุ

อาร์กิวเมนต์: substring String - สตริงย่อยที่จะค้นหา replacement String- สตริงที่จะแทนที่สตริงย่อย

ค่าการแสดงผล: String - สตริงใหม่หลังจากแทนที่สตริงย่อยด้วยการแทนที่

เมธอด replace() แตกต่างจากเมธอด replace() ของ JavaScript เล็กน้อยตรงที่จะแทนที่อินสแตนซ์ทั้งหมดของสตริงย่อยที่ระบุด้วยสตริงแทนที่ที่ระบุ ไม่ใช่แค่อินสแตนซ์แรก

เนื่องจากไม่อนุญาตให้ใช้จุดในคีย์ เราจึงต้องกำหนดสตริงเป็นอักขระหลีกด้วยจุดก่อนที่จะจัดเก็บ ตัวอย่างเช่น เกี่ยวกับอีเมล สมมติว่าเรามีรายการที่อยู่อีเมลที่อนุญาตพิเศษในโหนด /whitelist/ ของเรา:

{
 "user": {
   "$uid": {
     "email": <email>
   }
 },
 "whitelist": {
   "fred@gmail%2Ecom": true,
   "barney@aol%2Ecom": true
 }
}

เราสามารถสร้างกฎที่อนุญาตให้เพิ่มผู้ใช้ได้ต่อเมื่ออีเมลของผู้ใช้อยู่ในโหนด /whitelist/ เท่านั้น:

{
  "rules": {
    "users": {
      "$uid": {
        ".read": "true",
        ".write": "root.child('whitelist').child(newData.child('email').val().replace('.', '%2E')).exists()"
      }
    }
  }
}

ถึงตัวพิมพ์เล็ก()

แสดงผลสำเนาของสตริงที่แปลงเป็นตัวพิมพ์เล็ก

ผลลัพธ์ที่แสดง: String - สตริงที่แปลงเป็นตัวพิมพ์เล็ก

ตัวอย่างนี้ให้สิทธิ์อ่านหาก auth.token.identifier เป็นตัวพิมพ์เล็กทั้งหมดภายใต้ /users

".read": "root.child('users').child(auth.token.identifier.toLowerCase()).exists()"

เป็นตัวพิมพ์ใหญ่()

แสดงผลสำเนาของสตริงที่แปลงเป็นตัวพิมพ์ใหญ่

ผลลัพธ์ที่แสดง: String - สตริงที่แปลงเป็นอักษรตัวพิมพ์ใหญ่

ตัวอย่างนี้อนุญาตการเข้าถึงการอ่านหากมี auth.token.identifier เป็นตัวพิมพ์ใหญ่ทั้งหมดภายใต้ /users

".read": "root.child('users').child(auth.token.identifier.toUpperCase()).exists()"

ตรงกับ(นิพจน์ทั่วไป)

แสดงผลเป็น "จริง" หากสตริงตรงกับลิเทอรัลของนิพจน์ทั่วไปที่ระบุ

ผลลัพธ์: Boolean - true ถ้าสตริงตรงกับลิเทอรัลของนิพจน์ทั่วไป, regex; และอีก false

ดูเอกสารนิพจน์ทั่วไปของกฎฉบับเต็ม

โอเปอเรเตอร์

+ (เพิ่ม)

ใช้เพื่อเพิ่มตัวแปรหรือสำหรับการต่อสตริง

ตัวอย่างต่อไปนี้ช่วยให้แน่ใจว่าค่าใหม่จะเพิ่มค่าที่มีอยู่ทีละ 1 ค่า วิธีนี้มีประโยชน์ในการใช้ตัวนับ

".write": "newData.val() === data.val() + 1"
".validate": "root.child('room_names/' + $room_id).exists()"

- (ลบหรือลบ)

ใช้เพื่อลบล้างค่าหรือลบ 2 ค่าในนิพจน์กฎ

กฎการตรวจสอบนี้จะตรวจสอบว่าค่าใหม่จะผกผันกับค่าย่อยที่ตำแหน่งหรือไม่

".validate": "newData.val() === -(data.child('quantity').val())"

ตัวอย่างต่อไปนี้ใช้การลบเพื่อให้แน่ใจว่าจะอ่านได้เฉพาะข้อความในช่วง 10 นาทีที่ผ่านมา

".read": "newData.child('timestamp').val() > (now - 600000)"

* (คูณ)

ใช้เพื่อคูณตัวแปรในนิพจน์กฎ

กฎการตรวจสอบนี้จะตรวจสอบว่าค่าใหม่เท่ากับผลลัพธ์ของราคาและจำนวน (ค่าที่มีอยู่ 2 ค่า) ต่อไปนี้หรือไม่

".validate": "newData.val() === data.child('price').val() * data.child('quantity').val()"

/ (หาร)

ใช้เพื่อแบ่งตัวแปรในนิพจน์กฎ

ในตัวอย่างต่อไปนี้ กฎการตรวจสอบจะตรวจสอบว่าข้อมูลที่จัดเก็บไว้เป็นค่าเฉลี่ยของข้อมูลทั้งหมดที่เก็บไว้ที่อื่น

".validate": "newData.val() === data.parent().child('sum').val() / data.parent().child('numItems').val()"

% (โมดูลัส)

ใช้เพื่อหาเศษที่เหลือของหารตัวแปรหนึ่งด้วยตัวแปรอื่นในนิพจน์กฎ

กฎนี้ตรวจสอบว่า เขียนได้เฉพาะตัวเลขคู่เท่านั้น

".validate": "newData.val() % 2 === 0"

=== (เท่ากับ)

ใช้เพื่อตรวจสอบว่าตัวแปร 2 รายการในนิพจน์กฎมีประเภทและค่าเหมือนกันหรือไม่

กฎต่อไปนี้ใช้โอเปอเรเตอร์ === เพื่อให้สิทธิ์การเขียนแก่เจ้าของบัญชีผู้ใช้เท่านั้น UID ของผู้ใช้ต้องตรงกับคีย์ ($user_id) ทุกประการสำหรับกฎที่จะประเมินเป็นจริง

"users": {
  ".write": "$user_id === auth.uid"
}

!== (ไม่เท่ากับ)

ใช้เพื่อตรวจสอบว่าตัวแปร 2 รายการในนิพจน์กฎไม่เท่ากันหรือไม่

กฎการอ่านต่อไปนี้ช่วยให้มั่นใจว่าเฉพาะผู้ใช้ที่ลงชื่อเข้าใช้เท่านั้นที่จะอ่านข้อมูลได้

".read": "auth !== null"

&& (และ)

ประเมินเป็น "จริง" หากตัวถูกดำเนินการทั้งสองเป็นจริง ใช้เพื่อประเมินเงื่อนไขหลายรายการในนิพจน์กฎ

กฎการตรวจสอบความถูกต้องต่อไปนี้จะตรวจสอบว่าข้อมูลใหม่เป็นสตริงที่มีอักขระน้อยกว่า 100 ตัว

".validate": "newData.isString() && newData.val().length < 100"

|| (หรือ)

ประเมินเป็น "จริง" หากตัวถูกดำเนินการหนึ่งในนิพจน์กฎเป็นจริง

ในตัวอย่างนี้ เราสามารถเขียนได้ตราบใดที่ไม่มีข้อมูลเก่าหรือข้อมูลใหม่อยู่ กล่าวคือ เราเขียนได้ว่าเรากำลังลบหรือสร้างข้อมูล แต่ไม่อัปเดตข้อมูล

".write": "!data.exists() || !newData.exists()"

(ไม่ใช่)

ประเมินเป็น "จริง" หากตัวถูกดำเนินการเดี่ยวเป็น "เท็จ" ในนิพจน์กฎ เครื่องหมาย ! มักใช้เพื่อดูว่ามีการเขียนข้อมูลไปยังตำแหน่งหรือไม่

กฎต่อไปนี้จะให้สิทธิ์เขียนเฉพาะในกรณีที่ไม่มีข้อมูลที่ตำแหน่งที่ระบุ

".write": "!data.exists()"

(มากกว่า)

ใช้เพื่อตรวจสอบว่าค่ามากกว่าค่าอื่นในนิพจน์กฎ

กฎการตรวจสอบนี้จะตรวจสอบว่าสตริงที่เขียนไม่ใช่สตริงว่าง

".validate": "newData.isString() && newData.val().length > 0"

&lt; (น้อยกว่า)

ใช้เพื่อตรวจสอบว่าค่า i น้อยกว่าค่าอื่นในนิพจน์กฎหรือไม่

กฎการตรวจสอบนี้จะตรวจสอบว่าสตริงมีอักขระน้อยกว่า 20 ตัวหรือไม่ ดังนี้

".validate": "newData.isString() && newData.val().length < 20"

>= (มากกว่าหรือเท่ากับ)

ใช้เพื่อตรวจสอบว่าค่ามากกว่าหรือเท่ากับค่าอื่นในนิพจน์กฎ

กฎการตรวจสอบนี้จะตรวจสอบว่าสตริงที่เขียนไม่ใช่สตริงว่าง

".validate": "newData.isString() && newData.val().length >= 1"

<= (น้อยกว่าหรือเท่ากับ)

ใช้เพื่อตรวจสอบว่าค่าน้อยกว่าหรือเท่ากับค่าอื่นในนิพจน์กฎ

กฎการตรวจสอบความถูกต้องนี้ทำให้มั่นใจได้ว่าจะไม่สามารถเพิ่มข้อมูลใหม่ได้ในอนาคต

".validate": "newData.val() <= now"

(โอเปอเรเตอร์สามส่วน)

ใช้เพื่อประเมินนิพจน์กฎแบบมีเงื่อนไข

โอเปอเรเตอร์สามส่วนจะใช้ตัวถูกดำเนินการ 3 ตัว ตัวถูกดำเนินการก่อนเครื่องหมาย ? คือเงื่อนไข หากเงื่อนไขประเมินเป็น "จริง" ระบบจะประเมินตัวถูกดำเนินการที่ 2 หากเงื่อนไขเป็น "เท็จ" ระบบจะประเมินตัวถูกดำเนินการที่ 3

สำหรับกฎการตรวจสอบต่อไปนี้ ค่าใหม่สามารถเป็นตัวเลขหรือบูลีน หากเป็นตัวเลข ต้องมากกว่า 0

".validate": "newData.isNumber() ? newData.val() > 0 : newData.isBoolean()"