Pemicu Realtime Database

Dalam siklus proses umum, fungsi Firebase Realtime Database melakukan hal-hal berikut:

  1. Menunggu perubahan pada jalur Realtime Database tertentu.
  2. Terpicu ketika suatu peristiwa terjadi dan menjalankan tugasnya.
  3. Menerima objek data yang berisi snapshot data yang disimpan di jalur tersebut.

Anda dapat memicu fungsi sebagai respons terhadap penulisan, pembuatan, pembaruan, atau penghapusan node database di Firebase Realtime Database.

Memicu fungsi pada perubahan Firebase Realtime Database

Gunakan subpaket firebase-functions/v2/database untuk membuat fungsi yang menangani peristiwa Firebase Realtime Database. Untuk mengontrol kapan fungsi terpicu, tentukan salah satu pengendali peristiwa dan tentukan jalur Realtime Database tempat peristiwa akan diproses.

Menetapkan lokasi fungsi

Jarak antara lokasi instance Realtime Database dan lokasi fungsi dapat menyebabkan latensi jaringan yang signifikan. Selain itu, ketidakcocokan antara region dapat mengakibatkan kegagalan deployment. Untuk menghindari situasi tersebut, tentukan lokasi fungsi sehingga cocok dengan lokasi instance database.

Menangani peristiwa Realtime Database

Dengan Functions, Anda dapat menangani peristiwa Realtime Database di dua tingkat kekhususan; Anda dapat hanya memproses peristiwa penulisan, pembuatan, pembaruan, atau penghapusan secara khusus, atau Anda dapat memproses jenis perubahan apa pun pada referensi.

Tersedia pengendali berikut untuk merespons peristiwa Realtime Database:

  • onValueWritten() Hanya dipicu saat data ditulis di Realtime Database.
  • onValueCreated() Hanya dipicu saat data dibuat di Realtime Database.
  • onValueUpdated() Hanya dipicu saat data diperbarui di Realtime Database.
  • onValueDeleted() Hanya dipicu saat data dihapus di Realtime Database.

Menentukan instance dan jalur

Untuk mengontrol kapan dan di mana fungsi Anda harus terpicu, konfigurasikan fungsi dengan jalur dan, secara opsional, instance Realtime Database. Jika Anda tidak menentukan instance, fungsi tersebut akan di-deploy ke semua instance Realtime Database di region fungsi. Anda juga dapat menentukan pola instance Realtime Database yang akan di-deploy ke subset selektif instance di region yang sama.

Misalnya, menggunakan onValueWritten() untuk ilustrasi:

# All Realtime Database instances in default function region us-central1 at path "/user/{uid}"
# There must be at least one Realtime Database present in us-central1.
const onwrittenfunctiondefault = onValueWritten("/user/{uid}", (event) => {
  // …
});

# Instance named "my-app-db-2", at path "/user/{uid}".
# The "my-app-db-2" instance must exist in this region.
const onwrittenfunctioninstance = onValueWritten(
  {
    ref: "/user/{uid}",
    instance: "my-app-db-2"
    // This example assumes us-central1, but to set location:
    // region: "europe-west1"
  },
  (event) => {
    // …
  }
);

# Instance with "my-app-db-" prefix, at path "/user/{uid}", where uid ends with @gmail.com.
# There must be at least one Realtime Database with "my-app-db-*" prefix in this region.
const onwrittenfunctioninstance = onValueWritten(
  {
    ref: "/user/{uid=*@gmail.com}",
    instance: "my-app-db-*"
    // This example assumes us-central1, but to set location:
    // region: "europe-west1"
  },
  (event) => {
    // …
  }
);

Parameter ini akan mengarahkan fungsi Anda untuk menangani penulisan di jalur tertentu dalam instance Realtime Database.

Spesifikasi jalur cocok dengan semua penulisan yang menyentuh suatu jalur, termasuk penulisan yang terjadi di bawahnya. Jika Anda menetapkan /foo/bar sebagai jalur fungsi, jalur tersebut akan cocok dengan peristiwa di kedua lokasi ini:

 /foo/bar
 /foo/bar/baz/really/deep/path

Bagaimanapun juga, Firebase akan menafsirkan bahwa peristiwa terjadi di /foo/bar, dan data peristiwa menyertakan data lama dan baru di /foo/bar. Jika data peristiwa kemungkinan berukuran besar, sebaiknya gunakan beberapa fungsi di jalur yang lebih dalam, bukan fungsi tunggal di dekat root database Anda. Untuk mendapatkan performa terbaik, hanya minta data di level sedalam mungkin.

Karakter pengganti dan pengambilan

Anda dapat menggunakan {key}, {key=*}, {key=prefix*}, {key=*suffix} untuk pengambilan. *, prefix*, *suffix untuk karakter pengganti segmen tunggal. Catatan: ** merepresentasikan karakter pengganti multi-segmen, yang tidak didukung oleh RTDB. Lihat bagian Memahami pola jalur.

Karakter pengganti jalur. Anda dapat menentukan komponen jalur sebagai karakter pengganti:

  • Menggunakan tanda bintang, *. Misalnya, foo/* cocok dengan turunan mana pun dari satu level hierarki node di bawah foo/.
  • Menggunakan segmen yang berisi tanda bintang *. Misalnya, foo/app*-us cocok dengan segmen turunan di bawah foo/ dengan awalan app dan akhiran -us.

Jalur dengan karakter pengganti dapat cocok dengan beberapa peristiwa dari, misalnya, satu penulisan. Sisipan

{
  "foo": {
    "hello": "world",
    "firebase": "functions"
  }
}

cocok dengan jalur "/foo/*" dua kali: sekali dengan "hello": "world" dan sekali lagi dengan "firebase": "functions".

Pengambilan jalur. Anda dapat mengambil jalur yang cocok dan menyertakannya ke dalam variabel bernama untuk digunakan dalam kode fungsi Anda (misalnya /user/{uid}, /user/{uid=*-us}).

Nilai variabel pengambilan ini tersedia dalam objek database.DatabaseEvent.params dari fungsi Anda.

Karakter pengganti instance. Anda juga dapat menentukan komponen instance menggunakan karakter pengganti. Karakter pengganti instance dapat memiliki awalan, akhiran, atau keduanya (misalnya, my-app-*-prod).

Referensi karakter pengganti dan pengambilan

Dengan Cloud Functions (generasi ke-2) dan Realtime Database, suatu pola dapat digunakan saat menentukan ref dan instance. Setiap antarmuka pemicu akan memiliki opsi berikut untuk mencakup fungsi:

Menentukan ref Menentukan instance Perilaku
Tunggal (/foo/bar) Tidak menentukan Mencakup pengendali ke semua instance di region fungsi.
Tunggal (/foo/bar) Tunggal (‘my-new-db') Mencakup pengendali ke instance tertentu di region fungsi.
Tunggal (/foo/bar) Pola (‘inst-prefix*') Mencakup pengendali ke semua instance yang cocok dengan pola di region fungsi.
Pola (/foo/{bar}) Tidak menentukan Mencakup pengendali ke semua instance di region fungsi.
Pola (/foo/{bar}) Tunggal (‘my-new-db') Mencakup pengendali ke instance tertentu di region fungsi.
Pola (/foo/{bar}) Pola (‘inst-prefix*') Mencakup pengendali ke semua instance yang cocok dengan pola di region fungsi.

Menangani data peristiwa

Saat menangani peristiwa Realtime Database, objek data yang ditampilkan adalah DataSnapshot.

Untuk peristiwa onValueWritten atau onValueUpdated, parameter pertama adalah objek Change yang berisi dua snapshot yang mewakili status data sebelum dan setelah peristiwa pemicuan.

Untuk peristiwa onValueCreated dan onValueDeleted, objek data yang ditampilkan adalah snapshot dari data yang dibuat atau dihapus.

Dalam contoh ini, fungsi mengambil snapshot untuk jalur yang ditentukan foo/bar sebagai snap, mengubah string di lokasi tersebut menjadi huruf kapital, dan menulis string yang telah diubah tersebut ke database:

// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
export makeuppercase = onValueCreated("foo/bar", (event) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = event.data.val();
      functions.logger.log('Uppercasing', event.params.pushId, original);
      const uppercase = original.toUpperCase();
      // You must return a Promise when performing asynchronous tasks inside a Functions such as
      // writing to the Firebase Realtime Database.
      // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
      return event.data.ref.parent.child('uppercase').set(uppercase);
    });

Membaca nilai sebelumnya

Objek Change memiliki properti before yang dapat digunakan untuk memeriksa apa saja yang telah disimpan ke Realtime Database sebelum peristiwa. Properti before menampilkan DataSnapshot yang semua metodenya (misalnya, val() dan exists()) mengacu ke nilai sebelumnya. Anda dapat membaca kembali nilai baru menggunakan DataSnapshot yang asli atau membaca properti after. Di setiap Change, properti ini adalah DataSnapshot lain yang mewakili status data setelah peristiwa terjadi.

Misalnya, properti before dapat digunakan untuk memastikan bahwa fungsi hanya mengubah teks menjadi huruf kapital ketika pertama kali dibuat:

    exports makeuppercase = onValueWritten("/messages/{pushId}/original", (event) => {
          // Only edit data when it is first created.
          if (event.data.before.exists()) {
            return null;
          }
          // Exit when the data is deleted.
          if (!event.data.after.exists()) {
            return null;
          }
          // Grab the current value of what was written to the Realtime Database.
          const original = event.data.after.val();
          console.log('Uppercasing', event.params.pushId, original);
          const uppercase = original.toUpperCase();
          // You must return a Promise when performing asynchronous tasks inside a Functions such as
          // writing to the Firebase Realtime Database.
          // Setting an "uppercase" sibling in the Realtime Database returns a Promise.
          return event.data.after.ref.parent.child('uppercase').set(uppercase);
        });