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. Dengan begitu, Anda dapat menambahkan logika kustom tanpa men-deploy 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 dieksekusi 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 dalam project, Anda tidak boleh melakukan mutasi apa pun di handler pemicu atau Anda akan menyebabkan loop tak terbatas. Jika Anda ingin melakukan mutasi di pemicu peristiwa, gunakan opsi pemfilteran yang dijelaskan di bawah, dan pastikan mutasi tidak memicu dirinya sendiri.

Menetapkan lokasi fungsi

Lokasi fungsi harus cocok dengan Data Connect lokasi layanan agar peristiwa 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)

Karakter pengganti dan grup pengambilan

Anda dapat menggunakan karakter pengganti dan grup pengambilan untuk memfilter pemicu 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 mengetahui informasi selengkapnya tentang data yang tersedia dalam konteks autentikasi, lihat Konteks Autentikasi.

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 yang dimulai oleh authtype authid
Pengguna akhir yang diautentikasi app_user UID token Firebase Auth
Pengguna akhir yang tidak diautentikasi unauthenticated kosong
Admin SDK meniru pengguna akhir app_user UID token Firebase Auth pengguna yang di-impersonate
Admin SDK meniru permintaan yang tidak diautentikasi unauthenticated kosong
Admin SDK dengan izin penuh admin kosong

Mengakses data peristiwa

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

Atribut peristiwa

Atribut Jenis Deskripsi
id string ID unik untuk acara.
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 acara: 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 prinsipal yang memicu peristiwa.
authId string ID unik dari prinsipal yang memicu peristiwa.
data MutationEventData Payload peristiwa Data Connect. Lihat bagian berikutnya.

Payload 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 ditampilkan oleh mutasi.
  • payload.errors: Array error apa pun yang terjadi selama eksekusi mutasi. Jika mutasi berhasil, array 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.