Buka konsol

Memperluas Cloud Firestore dengan Cloud Functions

Dengan Cloud Functions, Anda dapat menerapkan kode Node.js untuk menangani peristiwa yang dipicu oleh perubahan pada database Cloud Firestore. Dengan begitu, Anda dapat menambahkan fungsionalitas sisi server ke aplikasi dengan mudah tanpa harus menjalankan server Anda sendiri.

Untuk contoh penggunaan, lihat Apa yang Dapat Dilakukan dengan Cloud Functions? atau Contoh Fungsi repositori GitHub.

Pemicu fungsi Cloud Firestore

Cloud Functions untuk Firebase SDK mengekspor objek functions.firestore yang memungkinkan Anda membuat pengendali yang terikat dengan peristiwa Cloud Firestore.

Jenis Peristiwa Pemicu
onCreate Dipicu saat dokumen ditulis untuk pertama kalinya.
onUpdate Dipicu saat dokumen sudah ada dan nilainya berubah.
onDelete Dipicu saat dokumen yang memuat data dihapus.
onWrite Dipicu saat onCreate, onUpdate atau onDelete dipicu.

Jika Anda belum memiliki project yang diaktifkan untuk Cloud Functions for Firebase, baca Memulai: Menulis dan Menerapkan Fungsi Pertama Anda untuk mengonfigurasi dan menyiapkan project Cloud Functions for Firebase.

Menulis fungsi yang dipicu oleh Cloud Firestore

Menentukan pemicu fungsi

Untuk menentukan pemicu Cloud Firestore, tentukan lokasi dokumen dan jenis peristiwa:

Node.js

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

exports.myFunction = functions.firestore
  .document('...')
  .onWrite((change, context) => { /* ... */ });

Lokasi dokumen dapat merujuk pada dokumen tertentu atau pola karakter pengganti.

Menentukan satu dokumen

Jika Anda ingin memicu suatu peristiwa untuk perubahan apa pun pada dokumen tertentu, maka Anda dapat menggunakan fungsi berikut.

Node.js

// Listen for any change on document `marie` in collection `users`
exports.myFunctionName = functions.firestore
    .document('users/marie').onWrite((change, context) => {
      // ... Your code here
    });

Menentukan grup dokumen menggunakan karakter pengganti

Jika Anda ingin melampirkan pemicu ke grup dokumen, seperti dokumen dalam koleksi tertentu, gunakan {wildcard} sebagai pengganti ID dokumen:

Node.js

// Listen for changes in all documents in the 'users' collection
exports.useWildcard = functions.firestore
    .document('users/{userId}')
    .onWrite((change, context) => {
      // If we set `/users/marie` to {name: "Marie"} then
      // context.params.userId == "marie"
      // ... and ...
      // change.after.data() == {name: "Marie"}
    });

Dalam contoh ini, saat kolom dalam dokumen pada users diubah, sistem akan mencocokkan karakter pengganti yang disebut userId.

Jika dokumen dalam users memiliki subkoleksi, dan kolom di salah satu dokumen subkoleksi tersebut diubah, userId karakter pengganti tidak akan terpicu.

Kecocokan karakter pengganti diekstrak dari lokasi dokumen dan disimpan ke dalam context.params. Anda dapat menentukan sebanyak mungkin karakter pengganti yang diinginkan untuk menggantikan koleksi eksplisit atau ID dokumen, misalnya:

Node.js

// Listen for changes in all documents in the 'users' collection and all subcollections
exports.useMultipleWildcards = functions.firestore
    .document('users/{userId}/{messageCollectionId}/{messageId}')
    .onWrite((change, context) => {
      // If we set `/users/marie/incoming_messages/134` to {body: "Hello"} then
      // context.params.userId == "marie";
      // context.params.messageCollectionId == "incoming_messages";
      // context.params.messageId == "134";
      // ... and ...
      // change.after.data() == {body: "Hello"}
    });

Pemicu Peristiwa

Memicu fungsi saat dokumen baru dibuat

Anda dapat memicu fungsi agar aktif setiap kali ada dokumen baru yang dibuat dalam koleksi menggunakan pengendali onCreate() dengan karakter pengganti. Fungsi contoh ini akan memanggil createUser setiap kali profil pengguna baru ditambahkan:

Node.js

exports.createUser = functions.firestore
    .document('users/{userId}')
    .onCreate((snap, context) => {
      // Get an object representing the document
      // e.g. {'name': 'Marie', 'age': 66}
      const newValue = snap.data();

      // access a particular field as you would any JS property
      const name = newValue.name;

      // perform desired operations ...
    });

Memicu fungsi saat dokumen diperbarui

Anda juga dapat memicu fungsi agar aktif saat dokumen diupdate menggunakan fungsi onUpdate() dengan karakter pengganti. Fungsi contoh ini akan memanggil updateUser jika pengguna mengubah profil mereka:

Node.js

exports.updateUser = functions.firestore
    .document('users/{userId}')
    .onUpdate((change, context) => {
      // Get an object representing the document
      // e.g. {'name': 'Marie', 'age': 66}
      const newValue = change.after.data();

      // ...or the previous value before this update
      const previousValue = change.before.data();

      // access a particular field as you would any JS property
      const name = newValue.name;

      // perform desired operations ...
    });

Memicu fungsi saat dokumen dihapus

Anda juga dapat memicu fungsi saat dokumen dihapus menggunakan fungsi onDelete() dengan karakter pengganti. Fungsi contoh ini akan memanggil deleteUser ketika pengguna menghapus profil pengguna mereka:

Node.js

exports.deleteUser = functions.firestore
    .document('users/{userID}')
    .onDelete((snap, context) => {
      // Get an object representing the document prior to deletion
      // e.g. {'name': 'Marie', 'age': 66}
      const deletedValue = snap.data();

      // perform desired operations ...
    });

Memicu fungsi untuk semua perubahan pada dokumen

Jika Anda tidak mementingkan jenis peristiwa yang diaktifkan, Anda dapat mendeteksi semua perubahan dalam dokumen Cloud Firestore menggunakan fungsi onWrite() dengankarakter pengganti. Fungsi contoh ini akan memanggil modifyUser jika pengguna dibuat, diupdate, atau dihapus:

Node.js

exports.modifyUser = functions.firestore
    .document('users/{userID}')
    .onWrite((change, context) => {
      // Get an object with the current document value.
      // If the document does not exist, it has been deleted.
      const document = change.after.exists ? change.after.data() : null;

      // Get an object with the previous document value (for update or delete)
      const oldDocument = change.before.data();

      // perform desired operations ...
    });

Membaca dan Menulis Data

Jika suatu fungsi dipicu, snapshot dari data yang terkait dengan peristiwa tersebut akan diberikan. Anda dapat menggunakan snapshot ini untuk membaca dari atau menulis ke dokumen yang memicu peristiwa, atau menggunakan Firebase Admin SDK untuk mengakses bagian lain dari database Anda.

Data Peristiwa

Membaca Data

Saat sebuah fungsi dipicu, Anda mungkin ingin mendapatkan data dari dokumen yang telah diperbarui, atau yang belum diperbarui. Anda bisa mendapatkan data sebelumnya menggunakan change.before.data(), yang berisi snapshot dokumen sebelum pembaruan dilakukan. Demikian pula, change.after.data() berisi status snapshot dokumen setelah pembaruan dilakukan.

Node.js

exports.updateUser = functions.firestore
    .document('users/{userId}')
    .onUpdate((change, context) => {
      // Get an object representing the current document
      const newValue = change.after.data();

      // ...or the previous value before this update
      const previousValue = change.before.data();
    });

Anda dapat mengakses properti sebagaimana Anda mengakses objek lainnya. Atau Anda dapat menggunakan fungsi get untuk mengakses kolom tertentu:

Node.js

// Fetch data using standard accessors
const age = snap.data().age;
const name = snap.data()['name'];

// Fetch data using built in accessor
const experience = snap.get('experience');

Menulis Data

Setiap pemanggilan fungsi dikaitkan dengan dokumen tertentu dalam database Cloud Firestore. Anda dapat mengakses dokumen tersebut sebagai DocumentReference di properti ref snapshot yang ditampilkan ke fungsi.

DocumentReference ini berasal dari Cloud Firestore Node.js SDK dan mencakup berbagai metode seperti update(), set(), dan remove() sehingga Anda dapat dengan mudah mengubah dokumen yang memicu fungsi tersebut.

Node.js

// Listen for updates to any `user` document.
exports.countNameChanges = functions.firestore
    .document('users/{userId}')
    .onUpdate((change, context) => {
      // Retrieve the current and previous value
      const data = change.after.data();
      const previousData = change.before.data();

      // We'll only update if the name has changed.
      // This is crucial to prevent infinite loops.
      if (data.name == previousData.name) return null;

      // Retrieve the current count of name changes
      let count = data.name_change_count;
      if (!count) {
        count = 0;
      }

      // Then return a promise of a set operation to update the count
      return change.after.ref.set({
        name_change_count: count + 1
      }, {merge: true});
    });

Data di luar peristiwa pemicu

Cloud Functions dijalankan dalam lingkungan tepercaya, yang berarti diotorisasi sebagai akun layanan di project Anda. Anda dapat melakukan pembacaan dan penulisan menggunakan Firebase Admin SDK:

Node.js

const admin = require('firebase-admin');
admin.initializeApp();

const db = admin.firestore();

exports.writeToFirestore = functions.firestore
  .document('some/doc')
  .onWrite((change, context) => {
    db.doc('some/otherdoc').set({ ... });
  });

Keterbatasan dan jaminan

Pemicu Cloud Firestore untuk Cloud Functions adalah fitur beta dengan beberapa keterbatasan umum:

  • Diperlukan waktu 10 detik hingga fungsi merespons perubahan di Cloud Firestore.
  • Pengurutan tidak dijamin. Perubahan cepat dapat memicu pemanggilan fungsi dalam urutan yang tidak terduga.
  • Peristiwa dikirim setidaknya satu kali, tetapi satu peristiwa dapat menghasilkan beberapa pemanggilan fungsi. Hindari mengandalkan mekanisme tepat satu kali, dan tulis fungsi idempoten.
  • Pemicu Cloud Firestore untuk Cloud Functions hanya tersedia untuk Cloud Firestore dalam mode Native. Pemicu ini tidak tersedia untuk Cloud Firestore dalam mode Datastore.