توسيع نطاق Data Connect باستخدام Cloud Functions

باستخدام Cloud Functions for Firebase، يمكنك التعامل مع الأحداث في Firebase Data Connect. تتيح لك Cloud Functions تنفيذ رمز من جهة الخادم استجابةً للأحداث، مثل تنفيذ عملية تغيير في خدمة Data Connect. يتيح لك ذلك إضافة منطق مخصّص بدون نشر خوادمك الخاصة.

حالات الاستخدام الشائعة

  • مزامنة البيانات: يمكنك تكرار البيانات أو مزامنتها مع أنظمة أخرى (مثل Cloud Firestore أو BigQuery أو واجهات برمجة التطبيقات الخارجية) بعد حدوث تغيير.

  • مهام سير العمل غير المتزامنة: يمكنك بدء عمليات تستغرق وقتًا طويلاً، مثل معالجة الصور أو تجميع البيانات، بعد إجراء تغيير في قاعدة البيانات.

  • تفاعل المستخدمين: يمكنك إرسال رسائل إلكترونية أو إشعارات Cloud Messaging إلى المستخدمين بعد وقوع حدث تغيير معيّن في تطبيقك، مثل إنشاء حساب.

تشغيل دالة عند حدوث تغيير في Data Connect

يمكنك تشغيل دالة كلما تم تنفيذ Data Connect عملية تغيير باستخدام معالج الأحداث onMutationExecuted. يتم تشغيل هذا المشغّل عند تنفيذ تغيير.

دالة حدث تغيير أساسية

المثال الأساسي التالي هو دالة تسجّل تفاصيل أي عملية تغيير يتم تنفيذها في خدمة Data Connect:

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)

عند تشغيل جميع عمليات التحوّل في مشروعك، يجب عدم إجراء أي عمليات تحوّل في معالج المشغّل، وإلا ستتسبب في حدوث حلقة لا نهائية. إذا أردت تنفيذ عمليات تغيير في مشغّل حدث، استخدِم خيارات الفلترة الموضّحة أدناه، وتأكَّد من أنّ عملية التغيير لا تؤدي إلى تشغيل نفسها.

تحديد موقع الدالة

يجب أن يتطابق الموقع الجغرافي للوظيفة مع الموقع الجغرافي للخدمة Data Connect حتى تؤدي الأحداث إلى تشغيل الوظيفة. تكون منطقة الدالة تلقائيًا 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

فلترة الأحداث

يمكن ضبط معالج onMutationExecuted باستخدام خيارات لفلترة الأحداث استنادًا إلى سمات معيّنة. يعد هذا مفيدًا عندما تريد فقط تشغيل وظيفتك لطفرات معينة.

يمكنك الفلترة حسب service وconnector و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)

أحرف البدل ومجموعات الالتقاط

يمكنك استخدام أحرف البدل ومجموعات الالتقاط لفلترة المشغّلات استنادًا إلى قيم متعدّدة. تتوفّر أي مجموعات تم تسجيلها في event.params لاستخدامها. راجِع مقالة فهم أنماط المسارات للحصول على مزيد من المعلومات.

أمثلة:

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

الوصول إلى معلومات مصادقة المستخدم

يمكنك الوصول إلى معلومات مصادقة المستخدم حول الجهة الرئيسية التي أدت إلى تشغيل الحدث. لمزيد من المعلومات حول البيانات المتاحة في سياق المصادقة، يُرجى الاطّلاع على سياق المصادقة.

يوضّح المثال التالي كيفية استرداد معلومات المصادقة:

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

سيتم ملء نوع المصادقة ومعرّف المصادقة على النحو التالي:

التغيير الذي بدأه authtype authid
المستخدم النهائي الذي تمت المصادقة عليه app_user معرّف UID لرمز Firebase Auth المميّز
المستخدم النهائي الذي لم تتم مصادقته unauthenticated فارغ
انتحال هوية مستخدم نهائي من خلال Admin SDK app_user المعرّف الفريد لرمز Firebase Auth المميّز للمستخدم الذي يتم انتحال هويته
حزمة تطوير البرامج (SDK) للمشرف تحاكي طلبًا لم تتم مصادقته unauthenticated فارغ
حزمة تطوير البرامج (SDK) للمشرف مع أذونات كاملة admin فارغ

الوصول إلى بيانات الأحداث

يحتوي العنصر CloudEvent الذي تم تمريره إلى الدالة على معلومات حول الحدث الذي أدّى إلى تشغيلها.

سمات الحدث

السمة النوع الوصف
id string تمثّل هذه السمة معرّفًا فريدًا للحدث.
source string مورد الموصّل الذي أنتج الحدث (على سبيل المثال، //firebasedataconnect.googleapis.com/projects/*/locations/*/services/*/connectors/*).
specversion string إصدار مواصفات CloudEvents (مثلاً، "1.0").
type string نوع الحدث: google.firebase.dataconnect.connector.v1.mutationExecuted
time string تمثّل هذه السمة الطابع الزمني (بتنسيق ISO 8601) لوقت إنشاء الحدث.
subject string اختياريّ. معلومات إضافية حول سياق الحدث، مثل اسم العملية.
params object خريطة لأنماط المسارات التي تم رصدها
authType string تعداد يمثّل نوع الجهة الرئيسية التي فعّلت الحدث.
authId string معرّف فريد للجهة الرئيسية التي أدّت إلى ظهور الحدث.
data MutationEventData حمولة حدث Data Connect يُرجى الاطّلاع على القسم التالي.

حمولة البيانات

يحتوي العنصر MutationEventData على حمولة الحدث 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: عنصر يحتوي على المتغيّرات التي تم تمريرها إلى عملية التغيير.
  • payload.data: عنصر يحتوي على البيانات التي تم عرضها بواسطة عملية التعديل.
  • payload.errors: مصفوفة تتضمّن أي أخطاء حدثت أثناء تنفيذ عملية التغيير. إذا نجح التغيير، ستكون هذه المصفوفة فارغة.

مثال

في ما يلي كيفية الوصول إلى متغيرات التغيير والبيانات التي تم إرجاعها:

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

يُرجى العِلم أنّه على عكس بعض مشغّلات قاعدة البيانات الأخرى، مثل Cloud Firestore أو Realtime Database، لا يوفّر الحدث Data Connect لقطة "قبل" للبيانات. بما أنّ Data Connect يرسل الطلبات إلى قاعدة البيانات الأساسية، لا يمكن الحصول على اللقطة "قبل" للبيانات بشكل متزامن. بدلاً من ذلك، يمكنك الوصول إلى الوسيطات المُرسَلة إلى عملية التغيير والبيانات التي تم إرجاعها من خلالها.

إحدى نتائج ذلك هي أنّه لا يمكنك استخدام استراتيجية مقارنة اللقطات "قبل" و "بعد" لتجنُّب الحلقات المفرغة التي يؤدي فيها عامل تشغيل حدث إلى تشغيل الحدث نفسه. إذا كان عليك تنفيذ عملية تغيير من دالة تم تشغيلها بواسطة حدث تغيير، استخدِم فلاتر الأحداث واحرص على التأكّد من أنّه لا يمكن لأي عملية تغيير أن تؤدي إلى تشغيل نفسها، حتى بشكل غير مباشر.