Ikuti semua informasi yang diumumkan di Firebase Summit, dan pelajari bagaimana Firebase dapat membantu Anda mempercepat pengembangan aplikasi dan menjalankan aplikasi dengan percaya diri. Pelajari Lebih Lanjut

Uji Aturan Keamanan Cloud Firestore Anda

Tetap teratur dengan koleksi Simpan dan kategorikan konten berdasarkan preferensi Anda.

Saat membuat aplikasi, Anda mungkin ingin mengunci akses ke database Cloud Firestore. Namun, sebelum meluncurkan, Anda memerlukan Aturan Keamanan Cloud Firestore yang lebih bernuansa. Dengan emulator Cloud Firestore, selain membuat prototipe dan menguji fitur dan perilaku umum aplikasi Anda , Anda dapat menulis pengujian unit yang memeriksa perilaku Aturan Keamanan Cloud Firestore Anda.

Mulai cepat

Untuk beberapa kasus pengujian dasar dengan aturan sederhana, cobalah contoh panduan memulai .

Memahami Aturan Keamanan Cloud Firestore

Terapkan Aturan Keamanan Firebase Authentication dan Cloud Firestore untuk autentikasi, otorisasi, dan validasi data tanpa server saat Anda menggunakan pustaka klien seluler dan web.

Aturan Keamanan Cloud Firestore mencakup dua bagian:

  1. Pernyataan match yang mengidentifikasi dokumen dalam database Anda.
  2. Ekspresi allow yang mengontrol akses ke dokumen tersebut.

Firebase Authentication memverifikasi kredensial pengguna dan menyediakan dasar untuk sistem akses berbasis pengguna dan berbasis peran.

Setiap permintaan basis data dari pustaka klien seluler/web Cloud Firestore dievaluasi berdasarkan aturan keamanan Anda sebelum membaca atau menulis data apa pun. Jika aturan menolak akses ke salah satu jalur dokumen yang ditentukan, seluruh permintaan akan gagal.

Pelajari lebih lanjut tentang Aturan Keamanan Cloud Firestore di Memulai Aturan Keamanan Cloud Firestore .

Instal emulatornya

Untuk menginstal emulator Cloud Firestore, gunakan Firebase CLI dan jalankan perintah di bawah ini:

firebase setup:emulators:firestore

Jalankan emulatornya

Mulailah dengan menginisialisasi proyek Firebase di direktori kerja Anda. Ini adalah langkah pertama yang umum saat menggunakan Firebase CLI .

firebase init

Mulai emulator menggunakan perintah berikut. Emulator akan berjalan hingga Anda mematikan prosesnya:

firebase emulators:start --only firestore

Dalam banyak kasus, Anda ingin memulai emulator, menjalankan rangkaian pengujian, lalu mematikan emulator setelah pengujian dijalankan. Anda dapat melakukannya dengan mudah menggunakan perintah emulators:exec :

firebase emulators:exec --only firestore "./my-test-script.sh"

Saat dimulai, emulator akan mencoba berjalan pada port default (8080). Anda dapat mengubah port emulator dengan memodifikasi bagian "emulators" dari file firebase.json Anda:

{
  // ...
  "emulators": {
    "firestore": {
      "port": "YOUR_PORT"
    }
  }
}

Sebelum Anda menjalankan emulator

Sebelum Anda mulai menggunakan emulator, perhatikan hal berikut:

  • Emulator awalnya akan memuat aturan yang ditentukan di bidang firestore.rules dari file firebase.json Anda. Ini mengharapkan nama file lokal yang berisi Aturan Keamanan Cloud Firestore Anda dan menerapkan aturan tersebut ke semua project. Jika Anda tidak menyediakan jalur file lokal atau menggunakan metode loadFirestoreRules seperti yang dijelaskan di bawah, emulator akan memperlakukan semua proyek sebagai memiliki aturan terbuka.
  • Meskipun sebagian besar SDK Firebase bekerja dengan emulator secara langsung, hanya @firebase/rules-unit-testing yang mendukung auth tiruan di Aturan Keamanan, sehingga pengujian unit menjadi lebih mudah. Selain itu, perpustakaan mendukung beberapa fitur khusus emulator seperti menghapus semua data, seperti yang tercantum di bawah ini.
  • Emulator juga akan menerima token Firebase Auth produksi yang disediakan melalui SDK Klien dan mengevaluasi aturan yang sesuai, yang memungkinkan menghubungkan aplikasi Anda langsung ke emulator dalam integrasi dan pengujian manual.

Jalankan pengujian unit lokal

Jalankan pengujian unit lokal dengan SDK JavaScript v9

Firebase mendistribusikan library pengujian unit Aturan Keamanan dengan SDK JavaScript versi 9 dan SDK versi 8. API perpustakaan sangat berbeda. Kami merekomendasikan library pengujian v9, yang lebih ramping dan memerlukan lebih sedikit penyiapan untuk terhubung ke emulator, sehingga dengan aman menghindari penggunaan sumber daya produksi yang tidak disengaja. Untuk kompatibilitas mundur, kami terus menyediakan pustaka pengujian v8 .

Gunakan @firebase/rules-unit-testing untuk berinteraksi dengan emulator yang berjalan secara lokal. Jika Anda mendapatkan error timeout atau ECONNREFUSED , periksa kembali apakah emulator benar-benar berjalan.

Kami sangat menyarankan untuk menggunakan Node.js versi terbaru sehingga Anda dapat menggunakan notasi async/await . Hampir semua perilaku yang mungkin ingin Anda uji melibatkan fungsi asinkron, dan modul pengujian dirancang untuk bekerja dengan kode berbasis Promise.

Pustaka Pengujian Unit Aturan v9 selalu mengetahui emulator dan tidak pernah menyentuh sumber daya produksi Anda.

Anda mengimpor perpustakaan menggunakan pernyataan impor modular v9. Sebagai contoh:

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.

Setelah diimpor, penerapan unit test melibatkan:

  • Membuat dan mengonfigurasi RulesTestEnvironment dengan panggilan ke initializeTestEnvironment .
  • Menyiapkan data pengujian tanpa memicu Aturan, menggunakan metode praktis yang memungkinkan Anda untuk mengabaikannya untuk sementara, RulesTestEnvironment.withSecurityRulesDisabled .
  • Menyiapkan test suite dan hook per-test sebelum/sesudah dengan panggilan untuk membersihkan data dan lingkungan pengujian, seperti RulesTestEnvironment.cleanup() atau RulesTestEnvironment.clearFirestore() .
  • Menerapkan kasus uji yang meniru status autentikasi menggunakan RulesTestEnvironment.authenticatedContext dan RulesTestEnvironment.unauthenticatedContext .

Metode umum dan fungsi utilitas

Lihat juga metode pengujian khusus emulator di SDK v9 .

initializeTestEnvironment() => RulesTestEnvironment

Fungsi ini menginisialisasi lingkungan pengujian untuk pengujian unit aturan. Panggil fungsi ini terlebih dahulu untuk pengaturan pengujian. Eksekusi yang berhasil membutuhkan emulator untuk dijalankan.

Fungsi menerima objek opsional yang mendefinisikan TestEnvironmentConfig , yang dapat terdiri dari ID proyek dan pengaturan konfigurasi emulator.

let testEnv = await initializeTestEnvironment({
  projectId: "demo-project-1234",
  firestore: {
    rules: fs.readFileSync("firestore.rules", "utf8"),
  },
});

RulesTestEnvironment.authenticatedContext({ user_id: string, tokenOptions?: TokenOptions }) => RulesTestContext

Metode ini membuat RulesTestContext , yang berperilaku seperti pengguna Otentikasi yang diautentikasi. Permintaan yang dibuat melalui konteks yang dikembalikan akan memiliki token Otentikasi tiruan yang dilampirkan. Secara opsional, teruskan objek yang mendefinisikan klaim khusus atau penggantian untuk muatan token Otentikasi.

Gunakan objek konteks pengujian yang dikembalikan dalam pengujian Anda untuk mengakses setiap instance emulator yang dikonfigurasi, termasuk yang dikonfigurasi dengan 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

Metode ini membuat RulesTestContext , yang berperilaku seperti klien yang tidak masuk melalui Otentikasi. Permintaan yang dibuat melalui konteks yang ditampilkan tidak akan menyertakan token Firebase Auth.

Gunakan objek konteks pengujian yang dikembalikan dalam pengujian Anda untuk mengakses setiap instance emulator yang dikonfigurasi, termasuk yang dikonfigurasi dengan 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()

Jalankan fungsi penyiapan pengujian dengan konteks yang berperilaku seolah-olah Aturan Keamanan dinonaktifkan.

Metode ini mengambil fungsi panggilan balik, yang mengambil konteks melewati Aturan Keamanan dan mengembalikan janji. Konteksnya akan hancur setelah janji diselesaikan / ditolak.

RulesTestEnvironment.cleanup()

Metode ini menghancurkan semua RulesTestContexts dibuat di lingkungan pengujian dan membersihkan sumber daya yang mendasarinya, memungkinkan keluar yang bersih.

Metode ini tidak mengubah status emulator dengan cara apa pun. Untuk menyetel ulang data di antara pengujian, gunakan metode clear data khusus emulator aplikasi.

assertSucceeds(pr: Promise<any>)) => Promise<any>

Ini adalah fungsi utilitas kasus uji.

Fungsi tersebut menegaskan bahwa Promise yang disertakan yang membungkus operasi emulator akan diselesaikan tanpa pelanggaran Aturan Keamanan.

await assertSucceeds(setDoc(alice.firestore(), '/users/alice'), { ... });

assertFails(pr: Promise<any>)) => Promise<any>

Ini adalah fungsi utilitas kasus uji.

Fungsi tersebut menegaskan bahwa Promise yang disertakan yang membungkus operasi emulator akan ditolak dengan pelanggaran Aturan Keamanan.

await assertFails(setDoc(alice.firestore(), '/users/bob'), { ... });

Metode khusus emulator

Lihat juga metode pengujian umum dan fungsi utilitas di SDK v9 .

RulesTestEnvironment.clearFirestore() => Promise<void>

Metode ini menghapus data dalam database Firestore milik projectId yang dikonfigurasi untuk emulator Firestore.

RulesTestContext.firestore(settings?: Firestore.FirestoreSettings) => Firestore;

Metode ini mendapatkan instance Firestore untuk konteks pengujian ini. Instance Firebase JS Client SDK yang dikembalikan dapat digunakan dengan API SDK klien (v9 modular atau v9 compat).

Visualisasikan evaluasi aturan

Emulator Cloud Firestore memungkinkan Anda memvisualisasikan permintaan klien di UI Emulator Suite, termasuk pelacakan evaluasi untuk Aturan Keamanan Firebase.

Buka tab Firestore > Permintaan untuk melihat urutan evaluasi mendetail untuk setiap permintaan.

Firestore Emulator Meminta Monitor yang menampilkan evaluasi Aturan Keamanan

Buat laporan pengujian

Setelah menjalankan serangkaian pengujian, Anda dapat mengakses laporan cakupan pengujian yang menunjukkan bagaimana setiap aturan keamanan Anda dievaluasi.

Untuk mendapatkan laporan, buat kueri titik akhir yang terbuka di emulator saat sedang berjalan. Untuk versi ramah browser, gunakan URL berikut:

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage.html

Ini memecah aturan Anda menjadi ekspresi dan subekspresi yang dapat Anda arahkan mouse untuk informasi selengkapnya, termasuk jumlah evaluasi dan nilai yang dikembalikan. Untuk versi JSON mentah dari data ini, sertakan URL berikut dalam kueri Anda:

http://localhost:8080/emulator/v1/projects/<project_id>:ruleCoverage

Perbedaan antara emulator dan produksi

  1. Anda tidak perlu membuat project Cloud Firestore secara eksplisit. Emulator secara otomatis membuat instance apa pun yang diakses.
  2. Emulator Cloud Firestore tidak berfungsi dengan alur Firebase Authentication normal. Sebagai gantinya, di Firebase Test SDK, kami telah menyediakan metode initializeTestApp() di pustaka rules-unit-testing , yang mengambil bidang auth . Pegangan Firebase yang dibuat menggunakan metode ini akan berperilaku seolah-olah telah berhasil diautentikasi sebagai entitas apa pun yang Anda berikan. Jika Anda memasukkan null , itu akan berperilaku sebagai pengguna yang tidak diautentikasi ( auth != null akan gagal, misalnya).

Memecahkan masalah yang diketahui

Saat menggunakan emulator Cloud Firestore, Anda mungkin mengalami masalah umum berikut. Ikuti panduan di bawah ini untuk memecahkan masalah perilaku tidak teratur yang Anda alami. Catatan ini ditulis dengan mempertimbangkan library pengujian unit Aturan Keamanan, tetapi pendekatan umum berlaku untuk semua SDK Firebase.

Perilaku tes tidak konsisten

Jika pengujian Anda terkadang lulus dan gagal, bahkan tanpa perubahan apa pun pada pengujian itu sendiri, Anda mungkin perlu memverifikasi bahwa pengujian tersebut diurutkan dengan benar. Sebagian besar interaksi dengan emulator bersifat asinkron, jadi periksa kembali apakah semua kode asinkron telah diurutkan dengan benar. Anda dapat memperbaiki urutan dengan merantai janji, atau menggunakan notasi await secara bebas.

Secara khusus, tinjau operasi asinkron berikut:

  • Menetapkan aturan keamanan, dengan, misalnya, initializeTestEnvironment .
  • Membaca dan menulis data, dengan, misalnya, db.collection("users").doc("alice").get() .
  • Pernyataan operasional, termasuk assertSucceeds dan assertFails .

Tes hanya lulus saat pertama kali Anda memuat emulator

Emulatornya stateful. Ini menyimpan semua data yang ditulis ke dalam memori, sehingga semua data hilang setiap kali emulator dimatikan. Jika Anda menjalankan beberapa pengujian terhadap id proyek yang sama, setiap pengujian dapat menghasilkan data yang mungkin memengaruhi pengujian berikutnya. Anda dapat menggunakan salah satu metode berikut untuk mengabaikan perilaku ini:

  • Gunakan ID proyek unik untuk setiap pengujian. Perhatikan bahwa jika Anda memilih untuk melakukan ini, Anda perlu memanggil initializeTestEnvironment sebagai bagian dari setiap pengujian; aturan hanya dimuat secara otomatis untuk ID proyek default.
  • Susun ulang pengujian Anda sehingga tidak berinteraksi dengan data yang ditulis sebelumnya (misalnya, gunakan koleksi yang berbeda untuk setiap pengujian).
  • Hapus semua data yang ditulis selama pengujian.

Pengaturan pengujian sangat rumit

Saat menyiapkan pengujian, Anda mungkin ingin mengubah data dengan cara yang sebenarnya tidak diizinkan oleh Aturan Keamanan Cloud Firestore Anda. Jika aturan Anda membuat penyiapan pengujian menjadi rumit, coba gunakan RulesTestEnvironment.withSecurityRulesDisabled dalam langkah penyiapan Anda, jadi membaca dan menulis tidak akan memicu kesalahan PERMISSION_DENIED .

Setelah itu, pengujian Anda dapat melakukan operasi sebagai pengguna yang diautentikasi atau tidak diautentikasi masing-masing menggunakan RulesTestEnvironment.authenticatedContext dan unauthenticatedContext . Ini memungkinkan Anda untuk memvalidasi bahwa Aturan Keamanan Cloud Firestore Anda mengizinkan/menolak kasus yang berbeda dengan benar.