ขณะที่สร้างแอป คุณอาจต้องล็อกการเข้าถึง ฐานข้อมูล Cloud Firestore อย่างไรก็ตาม ก่อนเปิดตัว คุณจะต้องปรับแต่งให้ละเอียดยิ่งขึ้น Cloud Firestore Security Rules นอกจากการสร้างต้นแบบด้วยโปรแกรมจำลอง Cloud Firestore แล้ว และทดสอบฟีเจอร์และลักษณะการทำงานทั่วไปของแอป คุณสามารถเขียนการทดสอบ 1 หน่วยที่จะตรวจสอบลักษณะการทำงานของ Cloud Firestore Security Rules ได้
คู่มือเริ่มใช้งานฉบับย่อ
สำหรับกรอบการทดสอบพื้นฐาน 2-3 กรณีที่มีกฎง่ายๆ ลองใช้ตัวอย่างการเริ่มต้นอย่างรวดเร็ว
ทำความเข้าใจ Cloud Firestore Security Rules
ใช้ Firebase Authentication และ Cloud Firestore Security Rules สำหรับการตรวจสอบสิทธิ์ การให้สิทธิ์ และการตรวจสอบข้อมูลแบบเซิร์ฟเวอร์เสมือนเมื่อใช้ไลบรารีไคลเอ็นต์เว็บและอุปกรณ์เคลื่อนที่
Cloud Firestore Security Rules ประกอบด้วย 2 ส่วน ดังนี้
- คำสั่ง
match
ที่ระบุเอกสารในฐานข้อมูลของคุณ - นิพจน์
allow
ที่ควบคุมการเข้าถึงเอกสารเหล่านั้น
Firebase Authentication ตรวจสอบข้อมูลเข้าสู่ระบบของผู้ใช้และเป็นรากฐานสําหรับระบบการเข้าถึงตามผู้ใช้และตามบทบาท
คำขอฐานข้อมูลทุกรายการจากไลบรารีของไคลเอ็นต์เว็บ/อุปกรณ์เคลื่อนที่ Cloud Firestore รายการ จะได้รับการประเมินตามกฎความปลอดภัยของคุณก่อนที่จะอ่านหรือเขียนข้อมูล ถ้ากฎปฏิเสธการเข้าถึงเส้นทางเอกสารที่ระบุ พารามิเตอร์ คำขอล้มเหลว
ดูข้อมูลเพิ่มเติมเกี่ยวกับ Cloud Firestore Security Rules ได้ในเริ่มต้นใช้งาน Cloud Firestore Security Rules
ติดตั้งโปรแกรมจำลอง
หากต้องการติดตั้งโปรแกรมจำลอง Cloud Firestore ให้ใช้ Firebase CLI และเรียกใช้คำสั่งด้านล่าง
firebase setup:emulators:firestore
เรียกใช้โปรแกรมจำลอง
เริ่มต้นโดยการเริ่มต้นโปรเจ็กต์ Firebase ในไดเรกทอรีการทำงาน นี่คือ ขั้นตอนแรกที่พบบ่อยเมื่อใช้ Firebase CLI
firebase init
เริ่มโปรแกรมจำลองโดยใช้คำสั่งต่อไปนี้ โปรแกรมจำลองจะทำงาน จนกว่าคุณจะจบกระบวนการ:
firebase emulators:start --only firestore
ในหลายกรณีที่คุณต้องการเริ่มโปรแกรมจำลอง ให้เรียกใช้ชุดทดสอบ จากนั้นจึงปิดโปรแกรม
ปิดโปรแกรมจำลองหลังจากทำการทดสอบ ซึ่งคุณดำเนินการได้ง่ายๆ โดยใช้
คำสั่ง emulators:exec
:
firebase emulators:exec --only firestore "./my-test-script.sh"
เมื่อเริ่มใช้งาน โปรแกรมจำลองจะพยายามเรียกใช้บนพอร์ตเริ่มต้น (8080) คุณสามารถ
เปลี่ยนพอร์ตโปรแกรมจำลองโดยแก้ไขส่วน "emulators"
ของ
ไฟล์ firebase.json
:
{ // ... "emulators": { "firestore": { "port": "YOUR_PORT" } } }
ก่อนเรียกใช้โปรแกรมจำลอง
ก่อนที่คุณจะเริ่มใช้โปรแกรมจำลอง โปรดคำนึงถึงสิ่งต่อไปนี้
- ในตอนแรกโปรแกรมจำลองจะโหลดกฎที่ระบุในช่อง
firestore.rules
ของไฟล์firebase.json
ควรมีชื่อของ ไฟล์ในเครื่องที่มี Cloud Firestore Security Rules ของคุณและใช้กฎเหล่านั้นกับ โปรเจ็กต์ หากไม่ได้ระบุเส้นทางไฟล์ในเครื่องหรือใช้เมธอด โปรแกรมจำลองจะพิจารณาเมธอดloadFirestoreRules
ตามที่อธิบายไว้ด้านล่าง ว่ามีกฎแบบเปิด - ขณะที่
Firebase SDK ส่วนใหญ่
ทำงานกับโปรแกรมจำลองโดยตรง มีเพียงไลบรารี
@firebase/rules-unit-testing
เท่านั้นที่รองรับ จำลองauth
ในกฎความปลอดภัย ทำให้การทดสอบ 1 หน่วยง่ายขึ้นมาก นอกจากนี้ ไลบรารีสนับสนุนคุณลักษณะเฉพาะโปรแกรมจำลองบางอย่าง เช่น การล้างข้อมูลทั้งหมด ตามที่ระบุไว้ด้านล่าง - โปรแกรมจำลองจะยอมรับโทเค็นการตรวจสอบสิทธิ์ Firebase เวอร์ชันที่ใช้งานจริงที่ให้ไว้ด้วย ผ่าน SDK ของไคลเอ็นต์ และประเมินกฎตามนั้น ซึ่งทำให้สามารถเชื่อมต่อ แอปพลิเคชันของคุณไปยังโปรแกรมจำลองโดยตรง ทั้งในแบบผสานรวมและการทดสอบด้วยตนเอง
เรียกใช้การทดสอบหน่วยในเครื่อง
เรียกใช้การทดสอบหน่วยในเครื่องด้วย JavaScript SDK v9
Firebase เผยแพร่ไลบรารีการทดสอบหน่วยของกฎการรักษาความปลอดภัยทั้งเวอร์ชัน JavaScript SDK 9 และ SDK เวอร์ชัน 8 API ของไลบรารี แตกต่างกัน เราขอแนะนำให้ใช้ไลบรารีการทดสอบ v9 ซึ่งมีประสิทธิภาพมากกว่าและ ใช้การตั้งค่าน้อยลงในการเชื่อมต่อกับโปรแกรมจำลองและหลีกเลี่ยงการเกิดอุบัติเหตุ การใช้ทรัพยากรการผลิต เรายังคงให้บริการคลังการทดสอบ v8 ต่อไปเพื่อให้ใช้งานย้อนหลังได้
- วิธีการทดสอบทั่วไปและฟังก์ชันยูทิลิตีใน SDK เวอร์ชัน 9
- วิธีทดสอบเฉพาะสำหรับโปรแกรมจำลองใน SDK เวอร์ชัน 9
ใช้โมดูล @firebase/rules-unit-testing
เพื่อโต้ตอบกับโปรแกรมจำลอง
ที่ทำงานภายในเครื่อง หากได้รับข้อผิดพลาดเกี่ยวกับเวลาหมดหรือ ECONNREFUSED
ให้ตรวจสอบอีกครั้งว่าโปรแกรมจำลองทำงานอยู่
เราขอแนะนำให้ใช้ Node.js เวอร์ชันล่าสุดเพื่อให้ใช้
รูปแบบ async/await
ลักษณะการทำงานเกือบทั้งหมดที่คุณอาจต้องการทดสอบ
รวมถึงฟังก์ชันแบบไม่พร้อมกัน และโมดูลการทดสอบได้รับการออกแบบมาให้ทำงานร่วมกับ
โค้ดที่อิงตามคำมั่นสัญญา
ไลบรารีการทดสอบหน่วยกฎ v9 จะรู้จักโปรแกรมจำลองเสมอและจะไม่เลย ทรัพยากรการผลิตของคุณ
คุณนำเข้าไลบรารีโดยใช้คำสั่งการนำเข้าแบบโมดูล v9 เช่น
import {
assertFails,
assertSucceeds,
initializeTestEnvironment
} from "@firebase/rules-unit-testing"
// Use `const { … } = require("@firebase/rules-unit-testing")` if imports are not supported
// Or we suggest `const testing = require("@firebase/rules-unit-testing")` if necessary.
เมื่อนำเข้าแล้ว การใช้การทดสอบ 1 หน่วยเกี่ยวข้องกับสิ่งต่อไปนี้
- การสร้างและกำหนดค่า
RulesTestEnvironment
ที่มีการเรียกinitializeTestEnvironment
- การตั้งค่าข้อมูลทดสอบโดยไม่ต้องเรียกใช้กฎ
ซึ่งจะช่วยให้คุณข้ามได้ชั่วคราว
RulesTestEnvironment.withSecurityRulesDisabled
- การตั้งค่าชุดทดสอบและตามการทดสอบก่อน/หลัง ฮุกที่มีการเรียก
ล้างข้อมูลและสภาพแวดล้อมการทดสอบ เช่น
RulesTestEnvironment.cleanup()
หรือRulesTestEnvironment.clearFirestore()
- การนำกรอบการทดสอบที่เลียนแบบสถานะการตรวจสอบสิทธิ์ไปใช้
RulesTestEnvironment.authenticatedContext
และRulesTestEnvironment.unauthenticatedContext
วิธีการทั่วไปและฟังก์ชันยูทิลิตี
โปรดดูวิธีทดสอบเฉพาะโปรแกรมจำลองใน SDK เวอร์ชัน 9
initializeTestEnvironment() => RulesTestEnvironment
ฟังก์ชันนี้จะเริ่มต้นสภาพแวดล้อมการทดสอบสำหรับการทดสอบหน่วยของกฎ เรียกใช้ฟังก์ชันนี้ก่อนเพื่อตั้งค่าการทดสอบ การดำเนินการที่ประสบความสำเร็จจำเป็นต้องมีโปรแกรมจำลอง วิ่งอยู่
ฟังก์ชันนี้จะยอมรับออบเจ็กต์ที่ไม่บังคับซึ่งกำหนด TestEnvironmentConfig
ซึ่งอาจประกอบด้วยรหัสโปรเจ็กต์และการตั้งค่าการจําลอง
let testEnv = await initializeTestEnvironment({ projectId: "demo-project-1234", firestore: { rules: fs.readFileSync("firestore.rules", "utf8"), }, });
RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext
วิธีนี้จะสร้าง RulesTestContext
ซึ่งจะทำงานเหมือนการตรวจสอบสิทธิ์
ผู้ใช้การตรวจสอบสิทธิ์ คำขอที่สร้างผ่านบริบทที่แสดงผลจะมีการจำลอง
แนบโทเค็นการตรวจสอบสิทธิ์แล้ว คุณเลือกที่จะส่งผ่านออบเจ็กต์ที่ระบุการอ้างสิทธิ์ที่กำหนดเอง หรือ
ลบล้างสำหรับเพย์โหลดโทเค็นการตรวจสอบสิทธิ์
ใช้ออบเจ็กต์บริบททดสอบที่ส่งคืนในการทดสอบเพื่อเข้าถึงโปรแกรมจำลอง
อินสแตนซ์ที่กำหนดค่าแล้ว รวมถึงอินสแตนซ์ที่กำหนดค่าด้วย initializeTestEnvironment
// Assuming a Firestore app and the Firestore emulator for this example import { setDoc } from "firebase/firestore"; const alice = testEnv.authenticatedContext("alice", { … }); // Use the Firestore instance associated with this context await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
RulesTestEnvironment.unauthenticatedContext() => RulesTestContext
วิธีนี้จะสร้าง RulesTestContext
ซึ่งมีลักษณะการทำงานเหมือนไคลเอ็นต์ที่
ไม่ได้เข้าสู่ระบบผ่านการตรวจสอบสิทธิ์ คำขอที่สร้างผ่านบริบทที่แสดงผลจะไม่
มีโทเค็นการตรวจสอบสิทธิ์ Firebase แนบอยู่
ใช้ออบเจ็กต์บริบททดสอบที่ส่งคืนในการทดสอบเพื่อเข้าถึงโปรแกรมจำลอง
อินสแตนซ์ที่กำหนดค่าแล้ว รวมถึงอินสแตนซ์ที่กำหนดค่าด้วย initializeTestEnvironment
// Assuming a Cloud Storage app and the Storage emulator for this example import { getStorage, ref, deleteObject } from "firebase/storage"; const alice = testEnv.unauthenticatedContext(); // Use the Cloud Storage instance associated with this context const desertRef = ref(alice.storage(), 'images/desert.jpg'); await assertSucceeds(deleteObject(desertRef));
RulesTestEnvironment.withSecurityRulesDisabled()
เรียกใช้ฟังก์ชันการตั้งค่าการทดสอบที่มีบริบทที่ทํางานเหมือนกับว่ากฎการรักษาความปลอดภัยถูกปิดใช้
วิธีนี้ใช้ฟังก์ชัน Callback ซึ่งจะใช้การข้ามกฎ Security บริบทที่เกี่ยวข้องและแสดงคำสัญญา บริบทจะถูกทำลายเมื่อสัญญา แก้ไข / ปฏิเสธ
RulesTestEnvironment.cleanup()
เมธอดนี้จะทำลาย RulesTestContexts
ทั้งหมดที่สร้างขึ้นในสภาพแวดล้อมการทดสอบและ
ทำความสะอาดทรัพยากรที่สำคัญ ทำให้สามารถออกได้อย่างสมบูรณ์
วิธีนี้จะไม่เปลี่ยนสถานะของโปรแกรมจำลองไม่ว่าในทางใดก็ตาม เพื่อรีเซ็ตข้อมูล ระหว่างการทดสอบ ให้ใช้วิธีการล้างข้อมูลเฉพาะแอปพลิเคชันโปรแกรมจำลอง
assertSucceeds(pr: Promise<any>)) => Promise<any>
นี่คือฟังก์ชันยูทิลิตีของเคสทดสอบ
ฟังก์ชันนี้จะยืนยันว่าการดำเนินการ Promise Wrapper ที่ระบุสิ้นสุดลง จะได้รับการแก้ไขโดยไม่ละเมิดกฎการรักษาความปลอดภัย
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
นี่คือฟังก์ชันยูทิลิตีของกรอบการทดสอบ
ฟังก์ชันนี้จะยืนยันว่าการดำเนินการ Promise Wrapper ที่ระบุสิ้นสุดลง จะถูกปฏิเสธเนื่องจากละเมิดกฎความปลอดภัย
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
วิธีการเฉพาะโปรแกรมจำลอง
ดูเมธอดการทดสอบทั่วไปและฟังก์ชันยูทิลิตีใน SDK เวอร์ชัน 9 ด้วย
RulesTestEnvironment.clearFirestore() => Promise<void>
วิธีนี้จะล้างข้อมูลในฐานข้อมูล Firestore ที่เป็นของ
กำหนดค่า projectId
สำหรับโปรแกรมจำลอง Firestore แล้ว
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
เมธอดนี้จะได้รับอินสแตนซ์ Firestore สำหรับบริบทการทดสอบนี้ ผลลัพธ์ อินสแตนซ์ SDK ของไคลเอ็นต์ Firebase JS ใช้ได้กับ API ของไคลเอ็นต์ SDK (v9 modular v9 modular) หรือความเข้ากันได้กับ v9)
แสดงภาพการประเมินกฎ
โปรแกรมจำลอง Cloud Firestore ช่วยให้คุณเห็นภาพคำขอของลูกค้าใน UI ของชุดโปรแกรมจำลอง รวมถึงการติดตามการประเมินกฎการรักษาความปลอดภัยของ Firebase
เปิด Firestore > แท็บคำขอเพื่อดูการประเมินโดยละเอียด ตามลำดับสำหรับแต่ละคำขอ
สร้างรายงานการทดสอบ
หลังจากใช้งานชุดการทดสอบแล้ว คุณจะเข้าถึงการทดสอบได้ รายงานที่ครอบคลุมซึ่งแสดงวิธีประเมินกฎความปลอดภัยแต่ละกฎ
หากต้องการดูรายงาน ให้ค้นหาปลายทางที่เปิดเผยในโปรแกรมจำลอง กำลังทำงาน สำหรับเวอร์ชันที่เหมาะสำหรับเบราว์เซอร์ ให้ใช้ URL ต่อไปนี้:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html
ซึ่งจะแบ่งกฎออกเป็นนิพจน์และนิพจน์ย่อยที่ วางเมาส์เหนือข้อมูลเพิ่มเติม รวมถึงจำนวนการประเมินและค่า ส่งคืนแล้ว สำหรับเวอร์ชันข้อมูลดิบ JSON ของข้อมูลนี้ ให้ใส่ URL ต่อไปนี้ ในข้อความค้นหาของคุณ:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage
ความแตกต่างระหว่างโปรแกรมจำลองกับเวอร์ชันที่ใช้งานจริง
- คุณไม่จำเป็นต้องสร้างโปรเจ็กต์ Cloud Firestore อย่างชัดเจน โปรแกรมจำลอง จะสร้างอินสแตนซ์ที่มีการเข้าถึงโดยอัตโนมัติ
- โปรแกรมจำลอง Cloud Firestore ไม่ทำงานกับขั้นตอน Firebase Authentication ปกติ
แต่ใน Firebase Test SDK เราได้ระบุเมธอด
initializeTestApp()
ไว้ในส่วน ไลบรารีrules-unit-testing
ซึ่งมีช่องauth
แฮนเดิล Firebase ที่สร้าง การใช้เมธอดนี้จะทำงานราวกับว่าได้ตรวจสอบสิทธิ์สำเร็จแล้ว เอนทิตีใดก็ตามที่คุณระบุ หากคุณผ่านในnull
จะมีลักษณะเหมือน ผู้ใช้ที่ไม่ได้รับการตรวจสอบสิทธิ์ (เช่น กฎauth != null
ข้อก็จะล้มเหลว)
แก้ปัญหาที่ทราบ
เมื่อคุณใช้โปรแกรมจำลอง Cloud Firestore คุณอาจพบปัญหาต่อไปนี้ ปัญหา ทำตามคำแนะนำด้านล่างเพื่อแก้ปัญหาการทำงานผิดปกติที่คุณพบ หมายเหตุเหล่านี้เขียนด้วยการทดสอบหน่วยกฎการรักษาความปลอดภัย ไลบรารีเดียวกัน แต่แนวทางทั่วไปใช้ได้กับ Firebase SDK
ลักษณะการทดสอบไม่สอดคล้องกัน
หากการทดสอบของคุณผ่านและไม่ผ่านเป็นครั้งคราว แม้ว่าจะไม่มีการเปลี่ยนแปลงการทดสอบเลย คุณอาจต้องตรวจสอบว่ามีการเรียงลำดับการทดสอบอย่างถูกต้อง
การโต้ตอบกับโปรแกรมจำลองส่วนใหญ่จะไม่พร้อมกัน ดังนั้นให้ตรวจสอบอีกครั้งว่า
มีการเรียงลำดับโค้ดอะซิงโครนัสอย่างถูกต้อง คุณสามารถแก้ไขการเรียงลําดับได้โดย
การทำห่วงโซ่สัญญาหรือใช้เครื่องหมาย await
อย่างเสรี
โดยเฉพาะอย่างยิ่ง โปรดตรวจสอบการดำเนินการที่ไม่พร้อมกันต่อไปนี้
- ตั้งกฎความปลอดภัย เช่น
initializeTestEnvironment
- การอ่านและการเขียนข้อมูล เช่น
db.collection("users").doc("alice").get()
- การยืนยันการดำเนินการ ซึ่งรวมถึง
assertSucceeds
และassertFails
การทดสอบจะผ่านในครั้งแรกที่คุณโหลดโปรแกรมจำลองเท่านั้น
โปรแกรมจำลองเป็นแบบเก็บสถานะ โดยระบบจะจัดเก็บข้อมูลทั้งหมดที่เขียนลงในหน่วยความจำ ดังนั้นข้อมูลทั้งหมดจะหายไปเมื่อปิดโปรแกรมจำลอง หากคุณใช้งาน โดยเทียบกับรหัสโครงการเดียวกัน การทดสอบแต่ละครั้งสามารถให้ข้อมูลที่อาจ ส่งผลต่อการทดสอบครั้งต่อๆ ไป คุณสามารถใช้วิธีการใดก็ได้ต่อไปนี้เพื่อ ให้หลีกเลี่ยงลักษณะการทำงานนี้
- ใช้รหัสโปรเจ็กต์ที่ไม่ซ้ำกันสำหรับการทดสอบแต่ละครั้ง โปรดทราบว่าหากคุณเลือกดำเนินการดังกล่าว
จะต้องโทรหา
initializeTestEnvironment
เป็นส่วนหนึ่งของการทดสอบแต่ละครั้ง กฎ จะโหลดโดยอัตโนมัติสำหรับรหัสโปรเจ็กต์เริ่มต้นเท่านั้น - ปรับโครงสร้างการทดสอบใหม่เพื่อไม่ให้โต้ตอบกับข้อมูลที่เขียนไว้ก่อนหน้านี้ (เช่น ใช้คอลเล็กชันอื่นสําหรับการทดสอบแต่ละรายการ)
- ลบข้อมูลทั้งหมดที่เขียนระหว่างการทดสอบ
การตั้งค่าการทดสอบซับซ้อนมาก
เมื่อตั้งค่าการทดสอบ คุณอาจต้องการแก้ไขข้อมูลในลักษณะ
Cloud Firestore Security Rules ไม่อนุญาต หากกฎของคุณตั้งค่าการทดสอบ
ซับซ้อน โปรดลองใช้ RulesTestEnvironment.withSecurityRulesDisabled
ในการตั้งค่า
ดังนั้นการอ่านและเขียนจะไม่ทริกเกอร์ข้อผิดพลาด PERMISSION_DENIED
รายการ
หลังจากนั้น การทดสอบของคุณสามารถดำเนินการต่างๆ ได้ตามสถานะที่ได้รับหรือไม่ผ่านการตรวจสอบสิทธิ์
ผู้ใช้ที่ใช้ RulesTestEnvironment.authenticatedContext
และ unauthenticatedContext
ตามลำดับ วิธีนี้ช่วยให้คุณตรวจสอบได้ว่า Cloud Firestore Security Rules อนุญาต/ปฏิเสธ เคสต่างๆ อย่างถูกต้อง