Khi xây dựng ứng dụng, bạn nên khoá quyền truy cập vào Cơ sở dữ liệu Cloud Firestore. Tuy nhiên, trước khi ra mắt, bạn cần có Cloud Firestore Security Rules chi tiết hơn. Với trình mô phỏng Cloud Firestore, ngoài việc chạy nguyên mẫu và kiểm thử các tính năng và hành vi chung của ứng dụng, bạn có thể viết mã kiểm thử đơn vị để kiểm tra hành vi của Cloud Firestore Security Rules.
Bắt đầu nhanh
Đối với một số trường hợp kiểm thử cơ bản có quy tắc đơn giản, hãy thử mẫu bắt đầu nhanh.
Tìm hiểu về Cloud Firestore Security Rules
Triển khai Firebase Authentication và Cloud Firestore Security Rules dành cho mô hình không máy chủ xác thực, uỷ quyền và xác thực dữ liệu khi bạn sử dụng thư viện ứng dụng web.
Cloud Firestore Security Rules bao gồm 2 phần:
- Câu lệnh
match
xác định các tài liệu trong cơ sở dữ liệu của bạn. - Biểu thức
allow
kiểm soát quyền truy cập vào các tài liệu đó.
Firebase Authentication xác minh thông tin xác thực của người dùng và cung cấp nền tảng cho các hệ thống truy cập dựa trên người dùng và vai trò.
Mọi yêu cầu cơ sở dữ liệu từ một thư viện ứng dụng web/dành cho thiết bị di động Cloud Firestore được đánh giá theo các quy tắc bảo mật trước khi đọc hoặc ghi bất kỳ dữ liệu nào. Nếu các quy tắc từ chối quyền truy cập vào bất kỳ đường dẫn tài liệu nào được chỉ định, thì toàn bộ đường dẫn không thành công.
Tìm hiểu thêm về Cloud Firestore Security Rules trong bài viết Bắt đầu sử dụng Cloud Firestore Security Rules.
Cài đặt trình mô phỏng
Để cài đặt trình mô phỏng Cloud Firestore, hãy sử dụng Firebase CLI rồi chạy lệnh bên dưới:
firebase setup:emulators:firestore
Chạy trình mô phỏng
Bắt đầu bằng cách khởi chạy một dự án Firebase trong thư mục đang hoạt động. Đây là một bước đầu tiên phổ biến khi sử dụng Giao diện dòng lệnh (CLI) của Firebase.
firebase init
Khởi động trình mô phỏng bằng lệnh sau. Trình mô phỏng sẽ chạy cho đến khi bạn dừng quá trình này:
firebase emulators:start --only firestore
Trong nhiều trường hợp, bạn muốn khởi động trình mô phỏng, chạy bộ kiểm thử rồi tắt
trình mô phỏng sau khi chạy thử nghiệm. Bạn có thể thực hiện việc này dễ dàng bằng cách sử dụng
Lệnh emulators:exec
:
firebase emulators:exec --only firestore "./my-test-script.sh"
Khi khởi động, trình mô phỏng sẽ cố chạy trên cổng mặc định (8080). Bạn có thể
thay đổi cổng trình mô phỏng bằng cách sửa đổi phần "emulators"
của
Tệp firebase.json
:
{ // ... "emulators": { "firestore": { "port": "YOUR_PORT" } } }
Trước khi bạn chạy trình mô phỏng
Trước khi bắt đầu sử dụng trình mô phỏng, hãy lưu ý những điều sau:
- Ban đầu, trình mô phỏng sẽ tải các quy tắc được chỉ định trong trường
firestore.rules
của tệpfirebase.json
. Tệp này sẽ yêu cầu tên của một tệp cục bộ chứa Cloud Firestore Security Rules và áp dụng các quy tắc đó cho tất cả dự án. Nếu bạn không cung cấp đường dẫn tệp trên máy hoặc sử dụngloadFirestoreRules
như mô tả dưới đây, trình mô phỏng sẽ xử lý tất cả dự án có các quy tắc mở. - Trong khi
hầu hết các SDK Firebase
làm việc trực tiếp với trình mô phỏng, thì chỉ thư viện
@firebase/rules-unit-testing
mới hỗ trợ mô phỏngauth
trong Quy tắc bảo mật, giúp việc kiểm thử đơn vị trở nên dễ dàng hơn nhiều. Ngoài ra, thư viện hỗ trợ một số tính năng dành riêng cho trình mô phỏng như xoá tất cả dữ liệu, như được liệt kê bên dưới. - Trình mô phỏng cũng sẽ chấp nhận mã thông báo xác thực Firebase chính thức được cung cấp thông qua SDK ứng dụng và đánh giá các quy tắc sao cho phù hợp, từ đó cho phép kết nối ứng dụng của bạn trực tiếp đến trình mô phỏng trong quá trình tích hợp và kiểm thử thủ công.
Chạy kiểm thử đơn vị cục bộ
Chạy kiểm thử đơn vị cục bộ với SDK JavaScript phiên bản 9
Firebase phân phối một thư viện kiểm thử đơn vị Quy tắc bảo mật kèm theo cả hai phiên bản 9 SDK JavaScript và SDK phiên bản 8 của SDK đó. Các API thư viện khác nhau đáng kể. Bạn nên sử dụng thư viện kiểm thử v9, thư viện này được tinh giản hơn và yêu cầu ít thiết lập hơn để kết nối với trình mô phỏng, nhờ đó tránh được việc vô tình sử dụng tài nguyên sản xuất một cách an toàn. Để đảm bảo khả năng tương thích ngược, chúng tôi tiếp tục cung cấp thư viện kiểm thử v8.
- Các phương pháp kiểm thử và hàm hiệu dụng phổ biến trong SDK phiên bản 9
- Các phương pháp kiểm thử dành riêng cho trình mô phỏng trong SDK phiên bản 9
Sử dụng mô-đun @firebase/rules-unit-testing
để tương tác với trình mô phỏng
chạy cục bộ. Nếu bạn thấy hết thời gian chờ hoặc gặp lỗi ECONNREFUSED
, hãy kiểm tra kỹ
trình mô phỏng đang thực sự chạy.
Bạn nên sử dụng phiên bản Node.js gần đây để có thể sử dụng
Ký hiệu async/await
. Hầu như tất cả các hành vi bạn có thể muốn kiểm tra
bao gồm các chức năng không đồng bộ và mô-đun kiểm thử được thiết kế để hoạt động
Mã dựa trên lời hứa.
Thư viện Kiểm thử đơn vị quy tắc v9 luôn nhận biết được trình mô phỏng và không bao giờ tác động đến nguồn lực sản xuất.
Bạn nhập thư viện bằng cách sử dụng câu lệnh nhập mô-đun v9. Ví dụ:
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.
Sau khi nhập, việc triển khai kiểm thử đơn vị bao gồm:
- Tạo và định cấu hình
RulesTestEnvironment
bằng lệnh gọi đếninitializeTestEnvironment
. - Thiết lập dữ liệu thử nghiệm mà không kích hoạt Quy tắc, sử dụng
cho phép bạn tạm thời bỏ qua chúng,
RulesTestEnvironment.withSecurityRulesDisabled
. - Thiết lập bộ thử nghiệm và mỗi lần kiểm thử trước/sau khi kết nối với các lệnh gọi đến
dọn dẹp dữ liệu và môi trường thử nghiệm, chẳng hạn như
RulesTestEnvironment.cleanup()
hoặcRulesTestEnvironment.clearFirestore()
. - Triển khai các trường hợp kiểm thử bắt chước trạng thái xác thực bằng cách sử dụng
RulesTestEnvironment.authenticatedContext
vàRulesTestEnvironment.unauthenticatedContext
.
Các phương thức và hàm hiệu dụng phổ biến
Ngoài ra, hãy xem các phương pháp kiểm thử dành riêng cho trình mô phỏng trong SDK phiên bản 9.
initializeTestEnvironment() => RulesTestEnvironment
Hàm này khởi chạy môi trường kiểm thử cho quy tắc kiểm thử đơn vị. Gọi sự kiện này đầu tiên để thiết lập thử nghiệm. Quá trình thực thi thành công đòi hỏi trình mô phỏng phải đang chạy.
Hàm này chấp nhận một đối tượng không bắt buộc xác định TestEnvironmentConfig
,
có thể bao gồm mã dự án và chế độ cài đặt cấu hình trình mô phỏng.
let testEnv = await initializeTestEnvironment({ projectId: "demo-project-1234", firestore: { rules: fs.readFileSync("firestore.rules", "utf8"), }, });
RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext
Phương thức này tạo ra một RulesTestContext
, hoạt động giống như mã xác thực
Người dùng xác thực. Các yêu cầu được tạo thông qua ngữ cảnh được trả về sẽ có một mã thông báo xác thực mô phỏng được đính kèm. Bạn có thể truyền một đối tượng xác định các thông báo xác nhận quyền sở hữu tuỳ chỉnh hoặc ghi đè cho tải trọng mã xác thực.
Sử dụng đối tượng ngữ cảnh kiểm thử được trả về trong các chương trình kiểm thử của bạn để truy cập vào bất kỳ trình mô phỏng nào
các thực thể được định cấu hình, bao gồm cả những thực thể được định cấu hình bằng 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
Phương thức này tạo ra một RulesTestContext
, hoạt động như một ứng dụng khách
chưa đăng nhập qua phần Xác thực. Các yêu cầu được tạo thông qua ngữ cảnh trả về sẽ không
đính kèm mã thông báo xác thực Firebase.
Sử dụng đối tượng ngữ cảnh kiểm thử được trả về trong các chương trình kiểm thử để truy cập vào mọi thực thể trình mô phỏng đã định cấu hình, bao gồm cả các thực thể được định cấu hình bằng 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()
Chạy một hàm thiết lập kiểm thử với ngữ cảnh hoạt động như thể Quy tắc bảo mật bị tắt.
Phương thức này sử dụng hàm callback, hàm này sẽ bỏ qua Security-Rules bối cảnh và trả về một lời hứa. Ngữ cảnh sẽ bị huỷ sau khi lời hứa giải quyết/từ chối.
RulesTestEnvironment.cleanup()
Phương thức này huỷ bỏ tất cả RulesTestContexts
được tạo trong môi trường kiểm thử và
dọn dẹp các tài nguyên cơ bản, cho phép thoát sạch.
Phương thức này không thay đổi trạng thái của trình mô phỏng theo bất kỳ cách nào. Cách đặt lại dữ liệu giữa các lần kiểm thử, hãy sử dụng phương thức xoá dữ liệu dành riêng cho trình mô phỏng ứng dụng.
assertSucceeds(pr: Promise<any>)) => Promise<any>
Đây là một hàm hiệu dụng trường hợp kiểm thử.
Hàm này xác nhận rằng Promise đã cung cấp sẽ gói một thao tác của trình mô phỏng sẽ được giải quyết mà không có vi phạm Quy tắc bảo mật nào.
await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });
assertFails(pr: Promise<any>)) => Promise<any>
Đây là một hàm hiệu dụng trường hợp kiểm thử.
Hàm này xác nhận rằng Promise đã cung cấp sẽ gói một thao tác của trình mô phỏng sẽ bị từ chối do vi phạm Quy tắc bảo mật.
await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });
Phương thức dành riêng cho trình mô phỏng
Ngoài ra, hãy xem các phương pháp kiểm thử và hàm hiệu dụng phổ biến trong SDK phiên bản 9.
RulesTestEnvironment.clearFirestore() => Promise<void>
Phương thức này xoá dữ liệu trong cơ sở dữ liệu Firestore thuộc về
Đã định cấu hình projectId
cho trình mô phỏng Firestore.
RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;
Phương thức này nhận một thực thể Firestore cho ngữ cảnh kiểm thử này. Được trả về Bạn có thể sử dụng phiên bản SDK ứng dụng Firebase JS với API SDK ứng dụng (mô-đun phiên bản 9 hoặc khả năng tương thích phiên bản 9).
Trực quan hoá việc đánh giá quy tắc
Trình mô phỏng Cloud Firestore cho phép bạn minh hoạ các yêu cầu của ứng dụng trong giao diện người dùng của Bộ công cụ mô phỏng, bao gồm cả hoạt động theo dõi đánh giá cho Quy tắc bảo mật của Firebase.
Mở Firestore > Thẻ Yêu cầu để xem nội dung đánh giá chi tiết trình tự cho mỗi yêu cầu.
Tạo báo cáo kiểm thử
Sau khi chạy một bộ thử nghiệm, bạn có thể truy cập vào báo cáo về mức độ phù hợp cho biết cách đánh giá từng quy tắc bảo mật của bạn.
Để nhận báo cáo, hãy truy vấn một điểm cuối hiển thị trên trình mô phỏng khi nó đang chạy. Đối với phiên bản thân thiện với trình duyệt, hãy sử dụng URL sau:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html
Thao tác này sẽ chia các quy tắc của bạn thành các biểu thức và biểu thức phụ mà bạn có thể di chuột qua để biết thêm thông tin, bao gồm số lượng đánh giá và giá trị bị trả lại. Đối với phiên bản JSON thô của dữ liệu này, hãy thêm URL sau trong truy vấn của bạn:
http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage
Sự khác biệt giữa trình mô phỏng và bản phát hành chính thức
- Bạn không cần phải tạo dự án Cloud Firestore một cách rõ ràng. Trình mô phỏng sẽ tự động tạo mọi thực thể được truy cập.
- Trình mô phỏng Cloud Firestore không hoạt động với quy trình Firebase Authentication thông thường.
Thay vào đó, trong SDK thử nghiệm Firebase, chúng tôi đã cung cấp phương thức
initializeTestApp()
trong Thư việnrules-unit-testing
, lấy trườngauth
. Đã tạo tên người dùng Firebase khi sử dụng phương thức này, phương thức này sẽ hoạt động như thể đã được xác thực thành công bất kỳ pháp nhân nào bạn cung cấp. Nếu bạn truyền vàonull
, mã này sẽ hoạt động như một người dùng chưa được xác thực (ví dụ:auth != null
quy tắc sẽ không thành công).
Khắc phục các vấn đề đã biết
Khi sử dụng trình mô phỏng Cloud Firestore, bạn có thể gặp phải các sự cố đã biết sau đây vấn đề. Hãy làm theo hướng dẫn dưới đây để khắc phục mọi hành vi bất thường mà bạn đang gặp phải đang trải nghiệm. Những ghi chú này được viết bằng cách kiểm thử đơn vị Quy tắc bảo mật nhưng các phương pháp chung đều có thể áp dụng cho mọi SDK Firebase.
Hoạt động thử nghiệm không nhất quán
Nếu các chương trình kiểm thử của bạn đôi khi đạt và không đạt, ngay cả khi bạn không thực hiện bất kỳ thay đổi nào
các bài kiểm thử, bạn có thể cần xác minh rằng các bài kiểm thử đó được sắp xếp theo trình tự đúng cách.
Hầu hết các hoạt động tương tác với trình mô phỏng đều không đồng bộ, vì vậy, hãy kiểm tra kỹ để đảm bảo tất cả
mã không đồng bộ được sắp xếp theo trình tự đúng cách. Bạn có thể khắc phục trình tự bằng
tạo chuỗi hứa hẹn hoặc thoải mái sử dụng ký hiệu await
.
Cụ thể, hãy xem lại các thao tác không đồng bộ sau:
- Đặt các quy tắc bảo mật với
initializeTestEnvironment
chẳng hạn. - Đọc và ghi dữ liệu, chẳng hạn như
db.collection("users").doc("alice").get()
. - Xác nhận hoạt động, bao gồm
assertSucceeds
vàassertFails
.
Các lượt kiểm thử chỉ đạt trong lần đầu tiên bạn tải trình mô phỏng
Trình mô phỏng có trạng thái. Phương thức này lưu trữ tất cả dữ liệu được ghi vào bộ nhớ, vì vậy, mọi dữ liệu sẽ bị mất mỗi khi trình mô phỏng tắt. Nếu bạn đang chạy nhiều thử nghiệm dựa trên cùng một mã dự án, mỗi thử nghiệm có thể cho ra dữ liệu ảnh hưởng đến các thử nghiệm tiếp theo. Bạn có thể dùng bất kỳ phương pháp nào sau đây để bỏ qua hành vi này:
- Sử dụng mã dự án duy nhất cho mỗi lần kiểm thử. Xin lưu ý rằng nếu chọn làm việc này, bạn
sẽ cần gọi
initializeTestEnvironment
trong mỗi lượt kiểm thử; quy tắc chỉ được tải tự động cho mã dự án mặc định. - Điều chỉnh cấu trúc chương trình kiểm thử để chúng không tương tác với dữ liệu đã ghi trước đây (ví dụ: sử dụng một tập hợp báo cáo riêng cho mỗi thử nghiệm).
- Xoá tất cả dữ liệu đã ghi trong quá trình kiểm thử.
Quá trình thiết lập thử nghiệm rất phức tạp
Khi thiết lập thử nghiệm, bạn nên sửa đổi dữ liệu theo cách
Cloud Firestore Security Rules không thực sự cho phép. Nếu các quy tắc của bạn đang khiến quy trình thiết lập kiểm thử trở nên phức tạp, hãy thử sử dụng RulesTestEnvironment.withSecurityRulesDisabled
trong các bước thiết lập để các thao tác đọc và ghi không kích hoạt lỗi PERMISSION_DENIED
.
Sau đó, quy trình kiểm thử của bạn có thể thực hiện các thao tác dưới dạng đối tượng đã được xác thực hoặc chưa được xác thực
người dùng sử dụng RulesTestEnvironment.authenticatedContext
và unauthenticatedContext
. Việc này giúp bạn xác thực rằng Cloud Firestore Security Rules cho phép / từ chối
các trường hợp khác nhau một cách chính xác.