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

Pemicu Basis Data Waktu Nyata

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

Dengan Cloud Functions, Anda dapat menangani peristiwa di Firebase Realtime Database tanpa perlu mengupdate kode klien. Cloud Functions memungkinkan Anda menjalankan operasi Realtime Database dengan hak istimewa administratif penuh, dan memastikan bahwa setiap perubahan pada Realtime Database diproses satu per satu. Anda dapat melakukan perubahan pada Firebase Realtime Database melalui DataSnapshot atau melalui Admin SDK .

Dalam siklus hidup biasa, fungsi Firebase Realtime Database melakukan hal berikut:

  1. Menunggu perubahan pada lokasi Realtime Database tertentu.
  2. Memicu saat peristiwa terjadi dan menjalankan tugasnya (lihat Apa yang dapat saya lakukan dengan Cloud Functions? untuk contoh kasus penggunaan).
  3. Menerima objek data yang berisi snapshot dari data yang disimpan dalam dokumen yang ditentukan.

Memicu fungsi Realtime Database

Buat fungsi baru untuk kejadian Realtime Database dengan functions.database . Untuk mengontrol kapan fungsi terpicu, tentukan salah satu penangan kejadian, dan tentukan jalur Realtime Database tempat ia akan mendengarkan kejadian.

Tetapkan pengendali acara

Fungsi memungkinkan Anda menangani kejadian Realtime Database pada dua tingkat kekhususan; Anda dapat mendengarkan secara khusus hanya untuk acara pembuatan, pembaruan, atau penghapusan, atau Anda dapat mendengarkan setiap perubahan apa pun pada jalur. Cloud Functions mendukung pengendali peristiwa ini untuk Realtime Database:

  • onWrite() , yang terpicu saat data dibuat, diperbarui, atau dihapus di Realtime Database.
  • onCreate() , yang terpicu saat data baru dibuat di Realtime Database.
  • onUpdate() , yang terpicu saat data diperbarui di Realtime Database .
  • onDelete() , yang terpicu saat data dihapus dari Realtime Database .

Tentukan instance dan path

Untuk mengontrol kapan dan di mana fungsi Anda harus dipicu, panggil ref(path) untuk menentukan jalur, dan secara opsional tentukan instance Realtime Database dengan instance('INSTANCE_NAME') . Jika Anda tidak menentukan instance, fungsi akan diterapkan ke instance Realtime Database default untuk project Firebase. Misalnya:

  • Contoh Database Realtime Default: functions.database.ref('/foo/bar')
  • Instance bernama "my-app-db-2": functions.database.instance('my-app-db-2').ref('/foo/bar')

Metode ini mengarahkan fungsi Anda untuk menangani penulisan pada jalur tertentu dalam instance Realtime Database. Spesifikasi jalur cocok dengan semua penulisan yang menyentuh jalur, termasuk penulisan yang terjadi di bawahnya. Jika Anda menyetel jalur untuk fungsi Anda sebagai /foo/bar , itu cocok dengan acara di kedua lokasi berikut:

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

Dalam kedua kasus tersebut, Firebase menginterpretasikan bahwa peristiwa terjadi di /foo/bar , dan data peristiwa menyertakan data lama dan baru di /foo/bar . Jika data peristiwa mungkin besar, pertimbangkan untuk menggunakan beberapa fungsi di jalur yang lebih dalam daripada satu fungsi di dekat akar database Anda. Untuk performa terbaik, hanya minta data pada level terdalam.

Anda dapat menentukan komponen jalur sebagai karakter pengganti dengan mengapitnya dengan tanda kurung kurawal; ref('foo/{bar}') cocok dengan anak mana pun dari /foo . Nilai komponen jalur wildcard ini tersedia dalam objek EventContext.params fungsi Anda. Dalam contoh ini, nilainya tersedia sebagai context.params.bar .

Jalur dengan wildcard dapat mencocokkan beberapa peristiwa dari satu penulisan. Sisipan dari

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

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

Menangani data peristiwa

Saat menangani kejadian Realtime Database, objek data yang dikembalikan adalah DataSnapshot . Untuk onWrite atau onUpdate , parameter pertama adalah objek Change yang berisi dua snapshot yang mewakili status data sebelum dan sesudah event pemicu. Untuk event onCreate dan onDelete , objek data yang dikembalikan adalah snapshot dari data yang dibuat atau dihapus.

Dalam contoh ini, fungsi mengambil snapshot untuk jalur yang ditentukan sebagai snap , mengonversi string di lokasi tersebut menjadi huruf besar, dan menulis string yang dimodifikasi itu ke database:

// Listens for new messages added to /messages/:pushId/original and creates an
// uppercase version of the message to /messages/:pushId/uppercase
exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snapshot, context) => {
      // Grab the current value of what was written to the Realtime Database.
      const original = snapshot.val();
      functions.logger.log('Uppercasing', context.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 snapshot.ref.parent.child('uppercase').set(uppercase);
    });

Mengakses informasi otentikasi pengguna

Dari EventContext.auth dan EventContext.authType , Anda bisa mengakses informasi pengguna, termasuk izin, untuk pengguna yang memicu suatu fungsi. Ini dapat berguna untuk menerapkan aturan keamanan, memungkinkan fungsi Anda menyelesaikan berbagai operasi berdasarkan tingkat izin pengguna:

const functions = require('firebase-functions');
const admin = require('firebase-admin');

exports.simpleDbFunction = functions.database.ref('/path')
    .onCreate((snap, context) => {
      if (context.authType === 'ADMIN') {
        // do something
      } else if (context.authType === 'USER') {
        console.log(snap.val(), 'written by', context.auth.uid);
      }
    });

Selain itu, Anda dapat memanfaatkan informasi autentikasi pengguna untuk "menyamar sebagai" pengguna dan melakukan operasi tulis atas nama pengguna. Pastikan untuk menghapus instance aplikasi seperti yang ditunjukkan di bawah ini untuk mencegah masalah konkurensi:

exports.impersonateMakeUpperCase = functions.database.ref('/messages/{pushId}/original')
    .onCreate((snap, context) => {
      const appOptions = JSON.parse(process.env.FIREBASE_CONFIG);
      appOptions.databaseAuthVariableOverride = context.auth;
      const app = admin.initializeApp(appOptions, 'app');
      const uppercase = snap.val().toUpperCase();
      const ref = snap.ref.parent.child('uppercase');

      const deleteApp = () => app.delete().catch(() => null);

      return app.database().ref(ref).set(uppercase).then(res => {
        // Deleting the app is necessary for preventing concurrency leaks
        return deleteApp().then(() => res);
      }).catch(err => {
        return deleteApp().then(() => Promise.reject(err));
      });
    });

Membaca nilai sebelumnya

Objek Change memiliki properti before yang memungkinkan Anda memeriksa apa yang telah disimpan ke Realtime Database sebelum acara. Properti before mengembalikan DataSnapshot di mana semua metode (misalnya, val() dan existing exists() ) merujuk ke nilai sebelumnya. Anda dapat membaca kembali nilai baru dengan menggunakan DataSnapshot asli atau membaca after properti. Properti ini pada Change apa pun adalah DataSnapshot lain yang mewakili status data setelah peristiwa terjadi.

Misalnya, properti before dapat digunakan untuk memastikan fungsi hanya teks huruf besar saat pertama kali dibuat:

exports.makeUppercase = functions.database.ref('/messages/{pushId}/original')
    .onWrite((change, context) => {
      // Only edit data when it is first created.
      if (change.before.exists()) {
        return null;
      }
      // Exit when the data is deleted.
      if (!change.after.exists()) {
        return null;
      }
      // Grab the current value of what was written to the Realtime Database.
      const original = change.after.val();
      console.log('Uppercasing', context.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 change.after.ref.parent.child('uppercase').set(uppercase);
    });