ขณะที่คุณกำลังสร้างแอป คุณอาจต้องการล็อคการเข้าถึงฐานข้อมูล Cloud Firestore ของคุณ อย่างไรก็ตาม ก่อนที่คุณจะเปิดตัว คุณต้องมีกฎการรักษาความปลอดภัยของ Cloud Firestore ที่เหมาะสมยิ่งขึ้น ด้วยโปรแกรมจำลอง Cloud Firestore นอกเหนือจากการสร้างต้นแบบและทดสอบ คุณลักษณะและลักษณะการทำงานทั่วไป ของแอปแล้ว คุณยังสามารถเขียนการทดสอบหน่วยเพื่อตรวจสอบพฤติกรรมของกฎความปลอดภัย Cloud Firestore ของคุณได้
เริ่มต้นอย่างรวดเร็ว
สำหรับกรณีทดสอบพื้นฐานสองสามข้อที่มีกฎง่ายๆ ให้ลองใช้ ตัวอย่างการเริ่มต้นอย่างรวดเร็ว
ทำความเข้าใจกฎความปลอดภัยของ Cloud Firestore
ใช้ Firebase Authentication และ Cloud Firestore Security Rules สำหรับการรับรองความถูกต้อง การอนุญาต และการตรวจสอบข้อมูลแบบไร้เซิร์ฟเวอร์เมื่อคุณใช้ไลบรารีไคลเอ็นต์บนมือถือและเว็บ
กฎการรักษาความปลอดภัยของ Cloud Firestore ประกอบด้วยสองส่วน:
- คำสั่งจับ
match
ที่ระบุเอกสารในฐานข้อมูลของคุณ - นิพจน์
allow
ที่ควบคุมการเข้าถึงเอกสารเหล่านั้น
Firebase Authentication จะตรวจสอบข้อมูลประจำตัวของผู้ใช้และเป็นพื้นฐานสำหรับระบบการเข้าถึงตามผู้ใช้และตามบทบาท
ทุกคำขอฐานข้อมูลจากไลบรารีไคลเอ็นต์มือถือ/เว็บ Cloud Firestore ได้รับการประเมินตามกฎความปลอดภัยของคุณก่อนที่จะอ่านหรือเขียนข้อมูลใดๆ หากกฎปฏิเสธการเข้าถึงเส้นทางเอกสารใดๆ ที่ระบุ คำขอทั้งหมดจะล้มเหลว
เรียนรู้เพิ่มเติมเกี่ยวกับกฎความปลอดภัยของ Cloud Firestore ใน เริ่มต้นใช้งานกฎความปลอดภัยของ Cloud Firestore
ติดตั้งโปรแกรมจำลอง
ในการติดตั้งโปรแกรมจำลอง 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 ของคุณและใช้กฎเหล่านั้นกับโครงการทั้งหมด หากคุณไม่ได้ระบุเส้นทางไฟล์ในเครื่องหรือใช้เมธอดloadFirestoreRules
ตามที่อธิบายไว้ด้านล่าง โปรแกรมจำลองจะถือว่าโปรเจ็กต์ทั้งหมดมีกฎเปิดอยู่ - แม้ว่า SDK ของ Firebase ส่วนใหญ่ จะทำงานร่วมกับโปรแกรมจำลองโดยตรง แต่ไลบรารี
@firebase/rules-unit-testing
เท่านั้นที่รองรับauth
การรับรองความถูกต้องในกฎความปลอดภัย ทำให้การทดสอบหน่วยง่ายขึ้นมาก นอกจากนี้ ไลบรารียังรองรับคุณสมบัติเฉพาะของอีมูเลเตอร์บางอย่าง เช่น การล้างข้อมูลทั้งหมด ดังที่แสดงด้านล่าง - ตัวเลียนแบบจะยอมรับโทเค็น Firebase Auth ที่ใช้งานจริงซึ่งให้ผ่าน Client SDK และประเมินกฎตามนั้น ซึ่งอนุญาตให้เชื่อมต่อแอปพลิเคชันของคุณกับตัวจำลองโดยตรงในการผสานรวมและการทดสอบด้วยตนเอง
เรียกใช้การทดสอบหน่วยท้องถิ่น
เรียกใช้การทดสอบหน่วยภายในด้วย v9 JavaScript SDK
Firebase เผยแพร่ไลบรารีการทดสอบหน่วยกฎความปลอดภัยที่มีทั้ง JavaScript SDK เวอร์ชัน 9 และ SDK เวอร์ชัน 8 API ของไลบรารีมีความแตกต่างกันอย่างมาก เราขอแนะนำไลบรารีการทดสอบ v9 ซึ่งมีความคล่องตัวมากกว่าและต้องการการตั้งค่าน้อยกว่าเพื่อเชื่อมต่อกับโปรแกรมจำลอง ดังนั้นจึงหลีกเลี่ยงการใช้ทรัพยากรการผลิตโดยไม่ตั้งใจได้อย่างปลอดภัย สำหรับความเข้ากันได้แบบย้อนหลัง เรายังคงให้ บริการไลบรารีการทดสอบ v8 ต่อไป
ใช้โมดูล @firebase/rules-unit-testing
เพื่อโต้ตอบกับโปรแกรมจำลองที่ทำงานในเครื่อง หากคุณได้รับการหมดเวลาหรือข้อผิดพลาด ECONNREFUSED
ให้ตรวจสอบอีกครั้งว่าโปรแกรมจำลองกำลังทำงานอยู่จริง
เราขอแนะนำอย่างยิ่งให้ใช้ Node.js เวอร์ชันล่าสุด เพื่อให้คุณสามารถใช้สัญลักษณ์ async/await
ได้ ลักษณะการทำงานเกือบทั้งหมดที่คุณอาจต้องการทดสอบเกี่ยวข้องกับฟังก์ชันแบบอะซิงโครนัส และโมดูลการทดสอบได้รับการออกแบบให้ทำงานกับรหัสตามสัญญา
ไลบรารี v9 Rules Unit Testing รับรู้ถึงโปรแกรมจำลองเสมอและไม่เคยแตะต้องทรัพยากรการผลิตของคุณ
คุณนำเข้าไลบรารีโดยใช้คำสั่งการนำเข้าโมดูลาร์ v9 ตัวอย่างเช่น:
import {
assertFails,
assertSucceeds,
initializeTestEnvironment,
RulesTestEnvironment,
} 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.
เมื่อนำเข้าแล้ว การดำเนินการทดสอบหน่วยเกี่ยวข้องกับ:
- การสร้างและกำหนด
RulesTestEnvironment
ด้วยการเรียกใช้initializeTestEnvironment
- การตั้งค่าข้อมูลการทดสอบโดยไม่เรียกใช้กฎ โดยใช้วิธีอำนวยความสะดวกที่ช่วยให้คุณข้ามกฎเหล่านั้นได้ชั่วคราว
RulesTestEnvironment.withSecurityRulesDisabled
- การตั้งค่าชุดการทดสอบและการทดสอบต่อครั้งก่อน/หลังการเชื่อมต่อด้วยการเรียกเพื่อล้างข้อมูลการทดสอบและสภาพแวดล้อม เช่น
RulesTestEnvironment.cleanup()
หรือRulesTestEnvironment.clearFirestore()
- การใช้กรณีทดสอบที่เลียนแบบสถานะการรับรองความถูกต้องโดยใช้
RulesTestEnvironment.authenticatedContext
และRulesTestEnvironment.unauthenticatedContext
วิธีการทั่วไปและฟังก์ชันยูทิลิตี้
ดู วิธีการทดสอบเฉพาะของอีมูเลเตอร์ใน v9 SDK
initializeTestEnvironment() => RulesTestEnvironment
ฟังก์ชันนี้เริ่มต้นสภาพแวดล้อมการทดสอบสำหรับการทดสอบหน่วยกฎ เรียกใช้ฟังก์ชันนี้ก่อนเพื่อทดสอบการตั้งค่า การดำเนินการที่ประสบความสำเร็จต้องใช้โปรแกรมจำลองในการทำงาน
ฟังก์ชันยอมรับออบเจกต์ทางเลือกที่กำหนด TestEnvironmentConfig
ซึ่งอาจประกอบด้วย ID โปรเจ็กต์และการตั้งค่าการกำหนดค่าอีมูเลเตอร์
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 Auth
ใช้ออบเจกต์บริบทการทดสอบที่ส่งคืนในการทดสอบของคุณเพื่อเข้าถึงอินสแตนซ์อีมูเลเตอร์ที่กำหนดค่าไว้ รวมถึงอินสแตนซ์ที่กำหนดค่าด้วย 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()
เรียกใช้ฟังก์ชันการตั้งค่าการทดสอบด้วยบริบทที่ทำงานเหมือนกับว่ากฎความปลอดภัยถูกปิดใช้งาน
วิธีนี้ใช้ฟังก์ชันการโทรกลับซึ่งใช้บริบทการข้ามกฎความปลอดภัยและส่งกลับสัญญา บริบทจะถูกทำลายเมื่อคำสัญญาแก้ไข/ปฏิเสธ
RulesTestEnvironment.cleanup()
เมธอดนี้จะทำลาย RulesTestContexts
ทั้งหมดที่สร้างขึ้นในสภาพแวดล้อมการทดสอบและล้างข้อมูลทรัพยากรพื้นฐาน ทำให้สามารถออกจากระบบได้ทั้งหมด
วิธีนี้ไม่ได้เปลี่ยนสถานะของอีมูเลเตอร์แต่อย่างใด หากต้องการรีเซ็ตข้อมูลระหว่างการทดสอบ ให้ใช้วิธีล้างข้อมูลเฉพาะของโปรแกรมจำลองแอปพลิเคชัน
assertSucceeds(pr: Promise<any>)) => Promise<any>
นี่คือฟังก์ชันยูทิลิตี้กรณีทดสอบ
ฟังก์ชันยืนยันว่า Promise ที่ให้มาซึ่งล้อมรอบการทำงานของโปรแกรมจำลองจะได้รับการแก้ไขโดยไม่มีการละเมิดกฎความปลอดภัย
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
นี่คือฟังก์ชันยูทิลิตี้กรณีทดสอบ
ฟังก์ชันยืนยันว่า Promise ที่ให้มาซึ่งห่อการทำงานของโปรแกรมจำลองจะถูกปฏิเสธด้วยการละเมิดกฎความปลอดภัย
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
วิธีการเฉพาะของอีมูเลเตอร์
ดู วิธีทดสอบทั่วไปและฟังก์ชันยูทิลิตี้ใน v9 SDK
RulesTestEnvironment.clearFirestore() => Promise<void>
วิธีนี้จะล้างข้อมูลในฐานข้อมูล Firestore ที่เป็นของ projectId
ที่กำหนดค่าสำหรับโปรแกรมจำลอง Firestore
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
วิธีนี้ได้รับอินสแตนซ์ของ Firestore สำหรับบริบทการทดสอบนี้ อินสแตนซ์ SDK ของไคลเอ็นต์ Firebase JS ที่ส่งคืนใช้กับไคลเอ็นต์ SDK API ได้ (v9 แบบโมดูลาร์หรือ v9 ที่เข้ากันได้)
เห็นภาพการประเมินกฎ
โปรแกรมจำลอง Cloud Firestore ช่วยให้คุณแสดงภาพคำขอของไคลเอ็นต์ใน Emulator Suite 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 ปกติ ใน Firebase Test SDK เราได้จัดเตรียมเมธอด
initializeTestApp()
ในไลบรารีrules-unit-testing
ซึ่งใช้ฟิลด์auth
ต้องแทน หมายเลขอ้างอิง Firebase ที่สร้างขึ้นโดยใช้วิธีนี้จะทำงานเหมือนกับว่าได้รับรองความถูกต้องสำเร็จเป็นเอนทิตีใดก็ตามที่คุณระบุ หากคุณส่งผ่านnull
มันจะทำงานเป็นผู้ใช้ที่ไม่ผ่านการรับรองความถูกต้อง (auth != null
จะล้มเหลว เป็นต้น)
แก้ไขปัญหาที่ทราบ
เมื่อคุณใช้โปรแกรมจำลอง Cloud Firestore คุณอาจพบปัญหาที่ทราบต่อไปนี้ ทำตามคำแนะนำด้านล่างเพื่อแก้ไขปัญหาพฤติกรรมผิดปกติที่คุณพบ หมายเหตุเหล่านี้เขียนขึ้นโดยคำนึงถึงไลบรารีการทดสอบหน่วยกฎความปลอดภัย แต่แนวทางทั่วไปใช้ได้กับ Firebase SDK ใดๆ
ลักษณะการทดสอบไม่สอดคล้องกัน
หากการทดสอบของคุณผ่านและล้มเหลวในบางครั้ง แม้จะไม่มีการเปลี่ยนแปลงใดๆ กับการทดสอบ คุณอาจต้องตรวจสอบว่ามีการจัดลำดับอย่างถูกต้อง การโต้ตอบกับโปรแกรมจำลองส่วนใหญ่จะเป็นแบบอะซิงโครนัส ดังนั้นควรตรวจสอบอีกครั้งว่าโค้ด async ทั้งหมดได้รับการจัดลำดับอย่างถูกต้อง คุณสามารถแก้ไขลำดับได้โดยการผูกสัญญาหรือใช้สัญกรณ์ await
อย่างเสรี
โดยเฉพาะอย่างยิ่ง ให้ตรวจสอบการดำเนินการ async ต่อไปนี้:
- การตั้งค่ากฎความปลอดภัย เช่น
initializeTestEnvironment
- การอ่านและเขียนข้อมูล เช่น
db.collection("users").doc("alice").get()
- การยืนยันการดำเนินการ รวมถึง
assertSucceeds
และassertFails
การทดสอบจะผ่านในครั้งแรกที่คุณโหลดโปรแกรมจำลองเท่านั้น
ตัวจำลองมีสถานะ มันเก็บข้อมูลทั้งหมดที่เขียนลงในหน่วยความจำ ดังนั้นข้อมูลใด ๆ จะสูญหายไปเมื่อใดก็ตามที่โปรแกรมจำลองปิดตัวลง หากคุณกำลังเรียกใช้การทดสอบหลายรายการกับรหัสโครงการเดียวกัน การทดสอบแต่ละครั้งสามารถสร้างข้อมูลที่อาจส่งผลต่อการทดสอบในครั้งต่อๆ ไป คุณสามารถใช้วิธีใดๆ ต่อไปนี้เพื่อหลีกเลี่ยงลักษณะการทำงานนี้:
- ใช้รหัสโครงการที่ไม่ซ้ำกันสำหรับการทดสอบแต่ละครั้ง โปรดทราบว่าหากคุณเลือกที่จะทำเช่นนี้ คุณจะต้องเรียก
initializeTestEnvironment
เป็นส่วนหนึ่งของการทดสอบแต่ละครั้ง กฎจะโหลดโดยอัตโนมัติสำหรับรหัสโครงการเริ่มต้นเท่านั้น - จัดโครงสร้างการทดสอบของคุณใหม่เพื่อไม่ให้โต้ตอบกับข้อมูลที่เขียนไว้ก่อนหน้านี้ (เช่น ใช้คอลเล็กชันที่แตกต่างกันสำหรับการทดสอบแต่ละครั้ง)
- ลบข้อมูลทั้งหมดที่เขียนระหว่างการทดสอบ
การตั้งค่าการทดสอบมีความซับซ้อนมาก
เมื่อตั้งค่าการทดสอบ คุณอาจต้องแก้ไขข้อมูลในลักษณะที่กฎความปลอดภัยของ Cloud Firestore ไม่อนุญาต หากกฎของคุณกำลังทำให้การตั้งค่าการทดสอบซับซ้อน ให้ลองใช้ RulesTestEnvironment.withSecurityRulesDisabled
ในขั้นตอนการตั้งค่าของคุณ ดังนั้นการอ่านและเขียนจะไม่ทำให้เกิดข้อผิดพลาด PERMISSION_DENIED
หลังจากนั้น การทดสอบของคุณสามารถดำเนินการในฐานะผู้ใช้ที่ผ่านการรับรองความถูกต้องหรือไม่ได้รับการตรวจสอบสิทธิ์ โดยใช้ RulesTestEnvironment.authenticatedContext
และ unauthenticatedContext
ตามลำดับ สิ่งนี้ช่วยให้คุณตรวจสอบว่ากฎความปลอดภัยของ Cloud Firestore อนุญาต / ปฏิเสธกรณีต่างๆ ได้อย่างถูกต้อง
ขณะที่คุณกำลังสร้างแอป คุณอาจต้องการล็อคการเข้าถึงฐานข้อมูล Cloud Firestore ของคุณ อย่างไรก็ตาม ก่อนที่คุณจะเปิดตัว คุณต้องมีกฎการรักษาความปลอดภัยของ Cloud Firestore ที่เหมาะสมยิ่งขึ้น ด้วยโปรแกรมจำลอง Cloud Firestore นอกเหนือจากการสร้างต้นแบบและทดสอบ คุณลักษณะและลักษณะการทำงานทั่วไป ของแอปแล้ว คุณยังสามารถเขียนการทดสอบหน่วยเพื่อตรวจสอบพฤติกรรมของกฎความปลอดภัย Cloud Firestore ของคุณได้
เริ่มต้นอย่างรวดเร็ว
สำหรับกรณีทดสอบพื้นฐานสองสามข้อที่มีกฎง่ายๆ ให้ลองใช้ ตัวอย่างการเริ่มต้นอย่างรวดเร็ว
ทำความเข้าใจกฎความปลอดภัยของ Cloud Firestore
ใช้ Firebase Authentication และ Cloud Firestore Security Rules สำหรับการรับรองความถูกต้อง การอนุญาต และการตรวจสอบข้อมูลแบบไร้เซิร์ฟเวอร์เมื่อคุณใช้ไลบรารีไคลเอ็นต์บนมือถือและเว็บ
กฎการรักษาความปลอดภัยของ Cloud Firestore ประกอบด้วยสองส่วน:
- คำสั่งจับ
match
ที่ระบุเอกสารในฐานข้อมูลของคุณ - นิพจน์
allow
ที่ควบคุมการเข้าถึงเอกสารเหล่านั้น
Firebase Authentication จะตรวจสอบข้อมูลประจำตัวของผู้ใช้และเป็นพื้นฐานสำหรับระบบการเข้าถึงตามผู้ใช้และตามบทบาท
ทุกคำขอฐานข้อมูลจากไลบรารีไคลเอ็นต์มือถือ/เว็บ Cloud Firestore ได้รับการประเมินตามกฎความปลอดภัยของคุณก่อนที่จะอ่านหรือเขียนข้อมูลใดๆ หากกฎปฏิเสธการเข้าถึงเส้นทางเอกสารใดๆ ที่ระบุ คำขอทั้งหมดจะล้มเหลว
เรียนรู้เพิ่มเติมเกี่ยวกับกฎความปลอดภัยของ Cloud Firestore ใน เริ่มต้นใช้งานกฎความปลอดภัยของ Cloud Firestore
ติดตั้งโปรแกรมจำลอง
ในการติดตั้งโปรแกรมจำลอง 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 ของคุณและใช้กฎเหล่านั้นกับโครงการทั้งหมด หากคุณไม่ได้ระบุเส้นทางไฟล์ในเครื่องหรือใช้เมธอดloadFirestoreRules
ตามที่อธิบายไว้ด้านล่าง โปรแกรมจำลองจะถือว่าโปรเจ็กต์ทั้งหมดมีกฎเปิดอยู่ - แม้ว่า SDK ของ Firebase ส่วนใหญ่ จะทำงานร่วมกับโปรแกรมจำลองโดยตรง แต่ไลบรารี
@firebase/rules-unit-testing
เท่านั้นที่รองรับauth
การรับรองความถูกต้องในกฎความปลอดภัย ทำให้การทดสอบหน่วยง่ายขึ้นมาก นอกจากนี้ ไลบรารียังรองรับคุณสมบัติเฉพาะของอีมูเลเตอร์บางอย่าง เช่น การล้างข้อมูลทั้งหมด ดังที่แสดงด้านล่าง - ตัวเลียนแบบจะยอมรับโทเค็น Firebase Auth ที่ใช้งานจริงซึ่งให้ผ่าน Client SDK และประเมินกฎตามนั้น ซึ่งอนุญาตให้เชื่อมต่อแอปพลิเคชันของคุณกับตัวจำลองโดยตรงในการผสานรวมและการทดสอบด้วยตนเอง
เรียกใช้การทดสอบหน่วยท้องถิ่น
เรียกใช้การทดสอบหน่วยภายในด้วย v9 JavaScript SDK
Firebase เผยแพร่ไลบรารีการทดสอบหน่วยกฎความปลอดภัยที่มีทั้ง JavaScript SDK เวอร์ชัน 9 และ SDK เวอร์ชัน 8 API ของไลบรารีมีความแตกต่างกันอย่างมาก เราขอแนะนำไลบรารีการทดสอบ v9 ซึ่งมีความคล่องตัวมากกว่าและต้องการการตั้งค่าน้อยกว่าเพื่อเชื่อมต่อกับโปรแกรมจำลอง ดังนั้นจึงหลีกเลี่ยงการใช้ทรัพยากรการผลิตโดยไม่ตั้งใจได้อย่างปลอดภัย สำหรับความเข้ากันได้แบบย้อนหลัง เรายังคงให้ บริการไลบรารีการทดสอบ v8 ต่อไป
ใช้โมดูล @firebase/rules-unit-testing
เพื่อโต้ตอบกับโปรแกรมจำลองที่ทำงานในเครื่อง หากคุณได้รับการหมดเวลาหรือข้อผิดพลาด ECONNREFUSED
ให้ตรวจสอบอีกครั้งว่าโปรแกรมจำลองกำลังทำงานอยู่จริง
เราขอแนะนำอย่างยิ่งให้ใช้ Node.js เวอร์ชันล่าสุด เพื่อให้คุณสามารถใช้สัญลักษณ์ async/await
ได้ ลักษณะการทำงานเกือบทั้งหมดที่คุณอาจต้องการทดสอบเกี่ยวข้องกับฟังก์ชันแบบอะซิงโครนัส และโมดูลการทดสอบได้รับการออกแบบให้ทำงานกับรหัสตามสัญญา
ไลบรารี v9 Rules Unit Testing รับรู้ถึงโปรแกรมจำลองเสมอและไม่เคยแตะต้องทรัพยากรการผลิตของคุณ
คุณนำเข้าไลบรารีโดยใช้คำสั่งการนำเข้าโมดูลาร์ v9 ตัวอย่างเช่น:
import {
assertFails,
assertSucceeds,
initializeTestEnvironment,
RulesTestEnvironment,
} 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.
เมื่อนำเข้าแล้ว การดำเนินการทดสอบหน่วยเกี่ยวข้องกับ:
- การสร้างและกำหนด
RulesTestEnvironment
ด้วยการเรียกใช้initializeTestEnvironment
- การตั้งค่าข้อมูลการทดสอบโดยไม่เรียกใช้กฎ โดยใช้วิธีอำนวยความสะดวกที่ช่วยให้คุณข้ามกฎเหล่านั้นได้ชั่วคราว
RulesTestEnvironment.withSecurityRulesDisabled
- การตั้งค่าชุดการทดสอบและการทดสอบต่อครั้งก่อน/หลังการเชื่อมต่อด้วยการเรียกเพื่อล้างข้อมูลการทดสอบและสภาพแวดล้อม เช่น
RulesTestEnvironment.cleanup()
หรือRulesTestEnvironment.clearFirestore()
- การใช้กรณีทดสอบที่เลียนแบบสถานะการรับรองความถูกต้องโดยใช้
RulesTestEnvironment.authenticatedContext
และRulesTestEnvironment.unauthenticatedContext
วิธีการทั่วไปและฟังก์ชันยูทิลิตี้
ดู วิธีการทดสอบเฉพาะของอีมูเลเตอร์ใน v9 SDK
initializeTestEnvironment() => RulesTestEnvironment
ฟังก์ชันนี้เริ่มต้นสภาพแวดล้อมการทดสอบสำหรับการทดสอบหน่วยกฎ เรียกใช้ฟังก์ชันนี้ก่อนเพื่อทดสอบการตั้งค่า การดำเนินการที่ประสบความสำเร็จต้องใช้โปรแกรมจำลองในการทำงาน
ฟังก์ชันยอมรับออบเจกต์ทางเลือกที่กำหนด TestEnvironmentConfig
ซึ่งอาจประกอบด้วย ID โปรเจ็กต์และการตั้งค่าการกำหนดค่าอีมูเลเตอร์
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 Auth
ใช้ออบเจกต์บริบทการทดสอบที่ส่งคืนในการทดสอบของคุณเพื่อเข้าถึงอินสแตนซ์อีมูเลเตอร์ที่กำหนดค่าไว้ รวมถึงอินสแตนซ์ที่กำหนดค่าด้วย 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()
เรียกใช้ฟังก์ชันการตั้งค่าการทดสอบด้วยบริบทที่ทำงานเหมือนกับว่ากฎความปลอดภัยถูกปิดใช้งาน
วิธีนี้ใช้ฟังก์ชันการโทรกลับซึ่งใช้บริบทการข้ามกฎความปลอดภัยและส่งกลับสัญญา บริบทจะถูกทำลายเมื่อคำสัญญาแก้ไข/ปฏิเสธ
RulesTestEnvironment.cleanup()
เมธอดนี้จะทำลาย RulesTestContexts
ทั้งหมดที่สร้างขึ้นในสภาพแวดล้อมการทดสอบและล้างข้อมูลทรัพยากรพื้นฐาน ทำให้สามารถออกจากระบบได้ทั้งหมด
วิธีนี้ไม่ได้เปลี่ยนสถานะของอีมูเลเตอร์แต่อย่างใด หากต้องการรีเซ็ตข้อมูลระหว่างการทดสอบ ให้ใช้วิธีล้างข้อมูลเฉพาะของโปรแกรมจำลองแอปพลิเคชัน
assertSucceeds(pr: Promise<any>)) => Promise<any>
นี่คือฟังก์ชันยูทิลิตี้กรณีทดสอบ
ฟังก์ชันยืนยันว่า Promise ที่ให้มาซึ่งล้อมรอบการทำงานของโปรแกรมจำลองจะได้รับการแก้ไขโดยไม่มีการละเมิดกฎความปลอดภัย
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
นี่คือฟังก์ชันยูทิลิตี้กรณีทดสอบ
ฟังก์ชันยืนยันว่า Promise ที่ให้มาซึ่งห่อการทำงานของโปรแกรมจำลองจะถูกปฏิเสธด้วยการละเมิดกฎความปลอดภัย
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
วิธีการเฉพาะของอีมูเลเตอร์
ดู วิธีทดสอบทั่วไปและฟังก์ชันยูทิลิตี้ใน v9 SDK
RulesTestEnvironment.clearFirestore() => Promise<void>
วิธีนี้จะล้างข้อมูลในฐานข้อมูล Firestore ที่เป็นของ projectId
ที่กำหนดค่าสำหรับโปรแกรมจำลอง Firestore
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
วิธีนี้ได้รับอินสแตนซ์ของ Firestore สำหรับบริบทการทดสอบนี้ อินสแตนซ์ SDK ของไคลเอ็นต์ Firebase JS ที่ส่งคืนใช้กับไคลเอ็นต์ SDK API ได้ (v9 แบบโมดูลาร์หรือ v9 ที่เข้ากันได้)
เห็นภาพการประเมินกฎ
โปรแกรมจำลอง Cloud Firestore ช่วยให้คุณแสดงภาพคำขอของไคลเอ็นต์ใน Emulator Suite 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 ปกติ ใน Firebase Test SDK เราได้จัดเตรียมเมธอด
initializeTestApp()
ในไลบรารีrules-unit-testing
ซึ่งใช้ฟิลด์auth
ต้องแทน หมายเลขอ้างอิง Firebase ที่สร้างขึ้นโดยใช้วิธีนี้จะทำงานเหมือนกับว่าได้รับรองความถูกต้องสำเร็จเป็นเอนทิตีใดก็ตามที่คุณระบุ หากคุณส่งผ่านnull
มันจะทำงานเป็นผู้ใช้ที่ไม่ผ่านการรับรองความถูกต้อง (auth != null
จะล้มเหลว เป็นต้น)
แก้ไขปัญหาที่ทราบ
เมื่อคุณใช้โปรแกรมจำลอง Cloud Firestore คุณอาจพบปัญหาที่ทราบต่อไปนี้ ทำตามคำแนะนำด้านล่างเพื่อแก้ไขปัญหาพฤติกรรมผิดปกติที่คุณพบ หมายเหตุเหล่านี้เขียนขึ้นโดยคำนึงถึงไลบรารีการทดสอบหน่วยกฎความปลอดภัย แต่แนวทางทั่วไปใช้ได้กับ Firebase SDK ใดๆ
ลักษณะการทดสอบไม่สอดคล้องกัน
หากการทดสอบของคุณผ่านและล้มเหลวในบางครั้ง แม้จะไม่มีการเปลี่ยนแปลงใดๆ กับการทดสอบ คุณอาจต้องตรวจสอบว่ามีการจัดลำดับอย่างถูกต้อง การโต้ตอบกับโปรแกรมจำลองส่วนใหญ่จะเป็นแบบอะซิงโครนัส ดังนั้นควรตรวจสอบอีกครั้งว่าโค้ด async ทั้งหมดได้รับการจัดลำดับอย่างถูกต้อง คุณสามารถแก้ไขลำดับได้โดยการผูกสัญญาหรือใช้สัญกรณ์ await
อย่างเสรี
โดยเฉพาะอย่างยิ่ง ให้ตรวจสอบการดำเนินการ async ต่อไปนี้:
- การตั้งค่ากฎความปลอดภัย เช่น
initializeTestEnvironment
- การอ่านและเขียนข้อมูล เช่น
db.collection("users").doc("alice").get()
- การยืนยันการดำเนินการ รวมถึง
assertSucceeds
และassertFails
การทดสอบจะผ่านในครั้งแรกที่คุณโหลดโปรแกรมจำลองเท่านั้น
ตัวจำลองมีสถานะ มันเก็บข้อมูลทั้งหมดที่เขียนลงในหน่วยความจำ ดังนั้นข้อมูลใด ๆ จะสูญหายไปเมื่อใดก็ตามที่โปรแกรมจำลองปิดตัวลง หากคุณกำลังเรียกใช้การทดสอบหลายรายการกับรหัสโครงการเดียวกัน การทดสอบแต่ละครั้งสามารถสร้างข้อมูลที่อาจส่งผลต่อการทดสอบในครั้งต่อๆ ไป คุณสามารถใช้วิธีใดๆ ต่อไปนี้เพื่อหลีกเลี่ยงลักษณะการทำงานนี้:
- ใช้รหัสโครงการที่ไม่ซ้ำกันสำหรับการทดสอบแต่ละครั้ง โปรดทราบว่าหากคุณเลือกที่จะทำเช่นนี้ คุณจะต้องเรียก
initializeTestEnvironment
เป็นส่วนหนึ่งของการทดสอบแต่ละครั้ง กฎจะโหลดโดยอัตโนมัติสำหรับรหัสโครงการเริ่มต้นเท่านั้น - จัดโครงสร้างการทดสอบของคุณใหม่เพื่อไม่ให้โต้ตอบกับข้อมูลที่เขียนไว้ก่อนหน้านี้ (เช่น ใช้คอลเล็กชันที่แตกต่างกันสำหรับการทดสอบแต่ละครั้ง)
- ลบข้อมูลทั้งหมดที่เขียนระหว่างการทดสอบ
การตั้งค่าการทดสอบมีความซับซ้อนมาก
เมื่อตั้งค่าการทดสอบ คุณอาจต้องแก้ไขข้อมูลในลักษณะที่กฎความปลอดภัยของ Cloud Firestore ไม่อนุญาต หากกฎของคุณกำลังทำให้การตั้งค่าการทดสอบซับซ้อน ให้ลองใช้ RulesTestEnvironment.withSecurityRulesDisabled
ในขั้นตอนการตั้งค่าของคุณ ดังนั้นการอ่านและเขียนจะไม่ทำให้เกิดข้อผิดพลาด PERMISSION_DENIED
หลังจากนั้น การทดสอบของคุณสามารถดำเนินการในฐานะผู้ใช้ที่ผ่านการรับรองความถูกต้องหรือไม่ได้รับการตรวจสอบสิทธิ์ โดยใช้ RulesTestEnvironment.authenticatedContext
และ unauthenticatedContext
ตามลำดับ สิ่งนี้ช่วยให้คุณตรวจสอบว่ากฎความปลอดภัยของ Cloud Firestore อนุญาต / ปฏิเสธกรณีต่างๆ ได้อย่างถูกต้อง