Memperluas Data Connect dengan Cloud Functions

Dengan Cloud Functions for Firebase, Anda dapat menangani peristiwa di Firebase Data Connect. Cloud Functions memungkinkan Anda menjalankan kode sisi server sebagai respons terhadap peristiwa, seperti eksekusi mutasi di layanan Data Connect Anda. Ini memungkinkan Anda menambahkan logika khusus tanpa harus menyebarkan server Anda sendiri.

Kasus penggunaan umum

  • Sinkronisasi Data: Mereplikasi atau menyinkronkan data dengan sistem lain (seperti Cloud Firestore, BigQuery, atau API eksternal) setelah mutasi terjadi.

  • Alur Kerja Asinkron: Memulai proses yang berjalan lama, seperti pemrosesan gambar atau agregasi data, setelah perubahan database.

  • Engagement pengguna: Kirim email atau notifikasi Cloud Messaging kepada pengguna setelah peristiwa mutasi tertentu di aplikasi Anda, seperti pembuatan akun.

Memicu fungsi saat terjadi mutasi Data Connect

Anda dapat memicu fungsi setiap kali mutasi Data Connect dijalankan menggunakan pengendali peristiwa onMutationExecuted. Pemicu ini terjadi saat eksekusi mutasi.

Fungsi peristiwa mutasi dasar

Contoh dasar berikut adalah fungsi yang mencatat detail mutasi apa pun yang dieksekusi di layanan Data Connect Anda:

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";
import { logger } from "firebase-functions";

export const logMutation = onMutationExecuted(
  {
    /* Trigger on all mutations, spanning all services and connectors
       in us-central1 */
  },
  (event) => {
    logger.info("A mutation was executed!", {
      data: event.data,
    });
  }
);

Python

from firebase_functions import dataconnect_fn, logger

@dataconnect_fn.on_mutation_executed()
def log_mutation(event: dataconnect_fn.Event):
  logger.info("A mutation was executed!", event.data)

Saat memicu semua mutasi pada proyek Anda, Anda tidak boleh melakukan mutasi apa pun pada pengendali pemicu atau Anda akan menyebabkan pengulangan tak terhingga. Jika Anda ingin melakukan mutasi pada pemicu peristiwa, gunakan opsi pemfilteran yang dijelaskan di bawah ini, dan pastikan mutasi tidak memicu dirinya sendiri.

Menetapkan lokasi fungsi

Itulokasi fungsi harus sesuai denganData Connect lokasi layanan untuk kejadian yang memicu fungsi. Secara default, region fungsi adalah us-central1.

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";

export const onMutationRegionOption = onMutationExecuted(
  {
    region: "europe-west1"  // Set if Data Connect service location is not us-central1
  },
  (event) => { /* ... */ }
);

Python

@dataconnect_fn.on_mutation_executed(
  region="europe-west1"  # Set if Data Connect service location is not us-central1
)
def mutation_executed_handler_region_option(event: dataconnect_fn.Event):
  pass

Filter peristiwa

Handler onMutationExecuted dapat dikonfigurasi dengan opsi untuk memfilter peristiwa berdasarkan atribut tertentu. Hal ini berguna saat Anda hanya ingin memicu fungsi untuk mutasi tertentu.

Anda dapat memfilter berdasarkan service, connector, dan operation:

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";
import { logger } from "firebase-functions";

// Trigger this function only for the CreateUser mutation
// in the users connector of the myAppService service.
export const onUserCreate = onMutationExecuted(
  {
    service: "myAppService",
    connector: "users",
    operation: "CreateUser",
  },
  (event) => {
    logger.info("A new user was created!", event.data);
    // Add logic here: for example, sending a welcome email.
  }
);

Python

from firebase_functions import dataconnect_fn, logger

@dataconnect_fn.on_mutation_executed(
  service="myAppService",
  connector="users",
  operation="CreateUser"
):
def on_user_create(event: dataconnect_fn.Event):
  logger.info("A new user was created!", event.data)

Wildcard dan grup penangkapan

Anda dapat menggunakan karakter pengganti dan grup penangkapan untuk memfilter pemicu Anda pada beberapa nilai. Grup yang diambil tersedia di event.params untuk digunakan. Lihat Memahami pola jalur untuk mengetahui informasi selengkapnya.

Contoh:

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";

// Trigger on all operations that match the pattern `User*`, on any service and
// connector.
export const onMutationWildcards = onMutationExecuted(
  {
    operation: "User*",
  },
  (event) => {}
);

// Trigger on all operations that match the pattern `User*`, on any service and
// connector. Capture the operation name in the variable `op`.
export const onMutationCaptureWildcards = onMutationExecuted(
  {
    operation: "{op=User*}",
  },
  (event) => {
    // `event.params.op` contains the operation name.
  }
);

// Trigger on all operations on the service `myAppService`. Capture the
// operation name in the variable `operation`.
export const onMutationCaptures = onMutationExecuted(
  {
    service: "myAppService",
    operation: "{operation}",
  },
  (event) => {
    // `event.params.operation` contains the operation name.
  }
);

Python

from firebase_functions import dataconnect_fn

# Trigger on all operations that match the pattern `User*`, on any service and
# connector.
@dataconnect_fn.on_mutation_executed(
  operation="User*"
)
def on_mutation_wildcards(event: dataconnect_fn.Event):
  pass

# Trigger on all operations that match the pattern `User*`, on any service and
# connector. Capture the operation name in the variable `op`.
@dataconnect_fn.on_mutation_executed(
  operation="{op=User*}"
)
def on_mutation_capture_wildcards(event: dataconnect_fn.Event):
  # `event.params["op"]` contains the operation name.
  pass

# Trigger on all operations on the service `myAppService`. Capture the
# operation name in the variable `operation`.
@dataconnect_fn.on_mutation_executed(
  service="myAppService",
  operation="{operation}"
)
def on_mutation_captures(event: dataconnect_fn.Event):
  # `event.params["operation"]` contains the operation name.
  pass

Mengakses informasi autentikasi pengguna

Anda dapat mengakses informasi autentikasi pengguna tentang akun utama yang memicu peristiwa tersebut. Untuk informasi selengkapnya tentang data yang tersedia dalam konteks autentikasi, lihat Konteks Otentikasi.

Contoh berikut menunjukkan cara mengambil informasi autentikasi:

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";

export const onMutation = onMutationExecuted(
  { operation: "MyMutation" },
  (event) => {
    // mutationExecuted event provides authType and authId:
    // event.authType
    // event.authId
  }
);

Python

from firebase_functions import dataconnect_fn

@dataconnect_fn.on_mutation_executed(operation="MyMutation")
def mutation_executed_handler(event: dataconnect_fn.Event):
  # mutationExecuted event provides auth_type and auth_id, which are accessed as follows
  # event.auth_type
  # event.auth_id
  pass

Jenis autentikasi dan ID autentikasi akan diisi sebagai berikut:

Mutasi dimulai oleh authtype authid
Pengguna akhir yang diautentikasi app_user UID token Otorisasi Firebase
Pengguna akhir yang tidak diautentikasi unauthenticated kosong
SDK Admin menyamar sebagai pengguna akhir app_user UID token Firebase Auth dari pengguna yang ditiru
Admin SDK meniru permintaan yang tidak diautentikasi unauthenticated kosong
Admin SDK dengan izin penuh admin kosong

Akses data acara

Objek CloudEvent yang diteruskan ke fungsi Anda berisi informasi tentang peristiwa yang memicunya.

Atribut peristiwa

Atribut Jenis Deskripsi
id string Pengidentifikasi unik untuk acara tersebut.
source string Resource konektor yang menghasilkan peristiwa (misalnya, //firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/*).
specversion string Versi spesifikasi CloudEvents (misalnya, "1.0").
type string Jenis kejadian: google.firebase.dataconnect.connector.v1.mutationExecuted.
time string Stempel waktu (format ISO 8601) saat acara dibuat.
subject string Opsional. Informasi tambahan tentang konteks peristiwa, seperti nama operasi.
params object Peta pola jalur yang direkam.
authType string Enum yang mewakili jenis pokok yang memicu peristiwa tersebut.
authId string Pengenal unik dari prinsipal yang memicu kejadian.
data MutationEventData Payload peristiwa Data Connect. Lihat bagian berikutnya.

Muatan data

Objek MutationEventData berisi payload peristiwa Data Connect:

{
  // ...
  "authType": // ...
  "data": {
    "payload": {
      "variables": {
        "userId": "user123",
        "updateData": {
          "displayName": "New Name"
        }
      },
      "data": {
        "updateUser": {
          "id": "user123",
          "displayName": "New Name",
          "email": "user@example.com"
        }
      },
      "errors": []
    }
  }
}
  • payload.variables: Objek yang berisi variabel yang diteruskan ke mutasi.
  • payload.data: Objek yang berisi data yang dikembalikan oleh mutasi.
  • payload.errors: Rangkaian kesalahan yang terjadi selama eksekusi mutasi. Jika mutasi berhasil, susunan ini akan kosong.

Contoh

Berikut cara mengakses variabel mutasi dan data yang ditampilkan:

Node.js

import { onMutationExecuted } from "firebase-functions/dataconnect";
import { logger } from "firebase-functions";

export const processNewUserData = onMutationExecuted(
  {
    "service": "myAppService",
    "connector": "users",
    "operation": "CreateUser",
  },
  (event) => {
    // The variables passed to the mutation
    const mutationVariables = event.data.payload.variables;

    // The data returned by the mutation
    const returnedData = event.data.payload.data;

    logger.info("Processing mutation with variables:", mutationVariables);
    logger.info("Mutation returned:", returnedData);

    // ... your custom logic here
  }
);

Python

from firebase_functions import dataconnect_fn, logger

@dataconnect_fn.on_mutation_executed(
  service="myAppService",
  connector="users",
  operation="CreateUser"
):
def process_new_user_data(event: dataconnect_fn.Event):
  # The variables passed to the mutation
  mutation_vars = event.data.payload.variables
  # The data returned by the mutation
  returned_data = event.data.payload.data

  logger.info("Processing mutation with variables:", mutationVariables)
  logger.info("Mutation returned", returnedData)

  # ... your custom logic here

Perhatikan bahwa tidak seperti pemicu database lainnya, seperti Cloud Firestore atau Realtime Database, peristiwa Data Connect tidak memberikan snapshot "sebelum" data. Karena Data Connect memproksi permintaan ke database pokok, snapshot "sebelum" data tidak dapat diperoleh secara transaksional. Sebagai gantinya, Anda memiliki akses ke argumen yang dikirim ke mutasi dan data yang dikembalikan olehnya.

Salah satu konsekuensinya adalah Anda tidak dapat menggunakan strategi membandingkan snapshot "sebelum" dan "sesudah" untuk menghindari loop tak terbatas, yang mana pemicu peristiwa memicu peristiwa yang sama. Jika Anda harus melakukan mutasi dari fungsi yang dipicu oleh peristiwa mutasi, gunakan filter peristiwa dan berhati-hatilah untuk memastikan bahwa tidak ada mutasi yang dapat memicu dirinya sendiri, bahkan secara tidak langsung.