ขยาย SQL Connect ด้วย Cloud Functions

Cloud Functions for Firebase ช่วยให้คุณจัดการเหตุการณ์ใน Firebase SQL Connect ได้ Cloud Functions ช่วยให้คุณเรียกใช้โค้ดฝั่งเซิร์ฟเวอร์เพื่อตอบสนองต่อเหตุการณ์ต่างๆ ได้ เช่น การดำเนินการเปลี่ยนแปลงในบริการ SQL Connect ซึ่งจะช่วยให้คุณเพิ่มตรรกะที่กำหนดเองได้โดยไม่ต้องติดตั้งใช้งานเซิร์ฟเวอร์ของคุณเอง

กรณีการใช้งานทั่วไป

  • การซิงค์ข้อมูล: จำลองหรือซิงค์ข้อมูลกับระบบอื่นๆ (เช่น Cloud Firestore, BigQuery หรือ API ภายนอก) หลังจากเกิดการเปลี่ยนแปลง

  • เวิร์กโฟลว์แบบอะซิงโครนัส: เริ่มกระบวนการที่ใช้เวลานาน เช่น การประมวลผลรูปภาพหรือการรวมข้อมูล หลังจากที่มีการเปลี่ยนแปลงฐานข้อมูล

  • การมีส่วนร่วมของผู้ใช้: ส่งอีเมลหรือการแจ้งเตือน Cloud Messaging ไปยังผู้ใช้หลังจากเหตุการณ์การปรับปรุงโครงสร้างที่เฉพาะเจาะจงในแอปพลิเคชัน เช่น การสร้างบัญชี

เรียกใช้ฟังก์ชันเมื่อมีการเปลี่ยนแปลง SQL Connect

คุณสามารถเรียกใช้ฟังก์ชันเมื่อใดก็ตามที่มีการดำเนินการเปลี่ยนแปลง SQL Connect โดยใช้ตัวแฮนเดิลเหตุการณ์ onMutationExecuted ทริกเกอร์นี้จะเกิดขึ้นเมื่อมีการดำเนินการ Mutation

ฟังก์ชันเหตุการณ์การปรับปรุงโครงสร้างพื้นฐาน

ตัวอย่างพื้นฐานต่อไปนี้คือฟังก์ชันที่บันทึกรายละเอียดของการเปลี่ยนแปลงที่ดำเนินการในบริการ SQL 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)

เมื่อทริกเกอร์การกลายพันธุ์ทั้งหมดในโปรเจ็กต์ คุณต้องไม่ทำการกลายพันธุ์ใดๆ ในตัวแฮนเดิลทริกเกอร์ ไม่เช่นนั้นจะทำให้เกิดลูปไม่สิ้นสุด หากต้องการทำการเปลี่ยนแปลงในทริกเกอร์เหตุการณ์ ให้ใช้ตัวเลือกการกรองที่อธิบายไว้ด้านล่าง และตรวจสอบว่าการเปลี่ยนแปลงไม่ได้ทริกเกอร์ตัวเอง

ตั้งค่าตำแหน่งของฟังก์ชัน

ตำแหน่งของฟังก์ชันต้องตรงกับตำแหน่งของบริการ SQL Connect เพื่อให้เหตุการณ์ทริกเกอร์ฟังก์ชันได้ โดยค่าเริ่มต้น ภูมิภาคของฟังก์ชันคือ us-central1

Node.js

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

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

Python

@dataconnect_fn.on_mutation_executed(
  region="europe-west1"  # Set if SQL 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 UID โทเค็น Firebase Auth ของผู้ใช้ที่ถูกแอบอ้าง
Admin SDK แอบอ้างเป็นคำขอที่ไม่ได้รับการตรวจสอบสิทธิ์ unauthenticated ว่าง
Admin 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 Enum ที่แสดงประเภทของ Principal ที่ทริกเกอร์เหตุการณ์
authId string ตัวระบุที่ไม่ซ้ำกันของ Principal ที่ทริกเกอร์เหตุการณ์
data MutationEventData เพย์โหลดของเหตุการณ์ SQL Connect ดูส่วนถัดไป

เพย์โหลดข้อมูล

ออบเจ็กต์ MutationEventData มีเพย์โหลดของเหตุการณ์ SQL 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

โปรดทราบว่าเหตุการณ์ SQL Connect จะไม่แสดงภาพรวม "ก่อนหน้า" ของข้อมูล ซึ่งแตกต่างจากทริกเกอร์ฐานข้อมูลอื่นๆ เช่น Cloud Firestore หรือ Realtime Database เนื่องจาก SQL Connect ส่งคำขอพร็อกซีไปยังฐานข้อมูลที่เกี่ยวข้อง จึงไม่สามารถรับสแนปชอต "ก่อนหน้า" ของข้อมูลในเชิงธุรกรรมได้ แต่คุณจะมีสิทธิ์เข้าถึงอาร์กิวเมนต์ที่ส่งไปยังการเปลี่ยนแปลงและข้อมูลที่แสดงผลจากการเปลี่ยนแปลงนั้น

ผลที่ตามมาอย่างหนึ่งคือ คุณไม่สามารถใช้กลยุทธ์การเปรียบเทียบภาพรวม "ก่อน" และ "หลัง" เพื่อหลีกเลี่ยงการวนซ้ำไม่สิ้นสุด ซึ่งทริกเกอร์เหตุการณ์จะทริกเกอร์เหตุการณ์เดียวกัน หากคุณต้องทำการปรับปรุงโครงสร้างจากฟังก์ชันที่ทริกเกอร์โดยเหตุการณ์การปรับปรุงโครงสร้าง ให้ใช้ตัวกรองเหตุการณ์และตรวจสอบว่าไม่มีการปรับปรุงโครงสร้างใดที่ทริกเกอร์ตัวเองได้ แม้จะเป็นทางอ้อมก็ตาม