טריגרים של אימות ב-Firebase

אפשר להפעיל פונקציות Cloud Run באמצעות אירועים מ-אימות ב-Firebase באותוGoogle Cloud פרויקט שבו מוגדרת הפונקציה. האירועים האלה כוללים יצירת משתמש ומחיקת משתמש. לדוגמה, אפשר לשלוח אימייל קבלת פנים למשתמש שרק יצר חשבון באפליקציה שלכם.

סוגי אירועים

האימות ב-Firebase יכול להפעיל פונקציות בתגובה לאירועים של create וdelete משתמשים.

סוג האירוע הטריגר
providers/firebase.auth/eventTypes/user.create מופעל כשנוצר חשבון משתמש.
providers/firebase.auth/eventTypes/user.delete מופעל כשחשבון משתמש נמחק.

יצירת משתמש

חשבונות Firebase מפעילים אירועים של יצירת משתמשים בפונקציות Cloud Run במקרים הבאים:

  • משתמש יוצר חשבון אימייל וסיסמה.

  • משתמש נכנס לחשבון בפעם הראשונה באמצעות ספק זהויות מאוחד.

  • המפתח יוצר חשבון באמצעות SDK של Firebase לאדמינים.

  • משתמש נכנס בפעם הראשונה לסשן חדש של אימות אנונימי.

מחיקת משתמש

אפשר גם להגדיר פונקציה שתופעל כשמשתמש נמחק.

מבנה האירוע

נתוני האירועים מסופקים כאובייקט UserRecord.

דוגמה לאירוע יצירה של חשבון שמבוסס על סיסמה מוצגת בהמשך:

{
  "email": "me@example.com",
  "metadata": {
      "createdAt": "2018-10-19T19:29:16Z"
  },
  "uid": "XXXXX"
}

חלק מהמאפיינים של האובייקט הזה מוגדרים רק כשמשתמשים בשיטות אימות מסוימות. לדוגמה, אירועים של חשבון שמבוסס על סיסמה מגדירים מאפיין email שמכיל את כתובת האימייל של המשתמש. המאפיין uid (שכולל מזהה משתמש ייחודי לפרויקט) מוגדר תמיד.

קוד לדוגמה

Node.js

/**
 * Background Function triggered by a change to a Firebase Auth user object.
 *
 * @param {!Object} event The Cloud Functions event.
 */
exports.helloAuth = event => {
  try {
    console.log(`Function triggered by change to user: ${event.uid}`);
    console.log(`Created at: ${event.metadata.createdAt}`);

    if (event.email) {
      console.log(`Email: ${event.email}`);
    }
  } catch (err) {
    console.error(err);
  }
};

Python

import json

def hello_auth(data, context):
    """Triggered by creation or deletion of a Firebase Auth user object.
    Args:
           data (dict): The event payload.
           context (google.cloud.functions.Context): Metadata for the event.
    """
    print("Function triggered by creation/deletion of user: %s" % data["uid"])
    print("Created at: %s" % data["metadata"]["createdAt"])

    if "email" in data:
        print("Email: %s" % data["email"])

Go


// Package firebase contains a Firestore Cloud Function.
package firebase

import (
	"context"
	"log"
	"time"
)

// AuthEvent is the payload of a Firestore Auth event.
type AuthEvent struct {
	Email    string `json:"email"`
	Metadata struct {
		CreatedAt time.Time `json:"createdAt"`
	} `json:"metadata"`
	UID string `json:"uid"`
}

// HelloAuth is triggered by Firestore Auth events.
func HelloAuth(ctx context.Context, e AuthEvent) error {
	log.Printf("Function triggered by creation or deletion of user: %q", e.UID)
	log.Printf("Created at: %v", e.Metadata.CreatedAt)
	if e.Email != "" {
		log.Printf("Email: %q", e.Email)
	}
	return nil
}

Java

import com.google.cloud.functions.Context;
import com.google.cloud.functions.RawBackgroundFunction;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.util.logging.Logger;

public class FirebaseAuth implements RawBackgroundFunction {
  private static final Logger logger = Logger.getLogger(FirebaseAuth.class.getName());

  // Use GSON (https://github.com/google/gson) to parse JSON content.
  private static final Gson gson = new Gson();

  @Override
  public void accept(String json, Context context) {
    JsonObject body = gson.fromJson(json, JsonObject.class);

    if (body != null && body.has("uid")) {
      logger.info("Function triggered by change to user: " + body.get("uid").getAsString());
    }

    if (body != null && body.has("metadata")) {
      JsonObject metadata = body.get("metadata").getAsJsonObject();
      logger.info("Created at: " + metadata.get("createdAt").getAsString());
    }

    if (body != null && body.has("email")) {
      logger.info("Email: " + body.get("email").getAsString());
    }
  }
}

C#‎

using CloudNative.CloudEvents;
using Google.Cloud.Functions.Framework;
using Google.Events.Protobuf.Firebase.Auth.V1;
using Microsoft.Extensions.Logging;
using System.Threading;
using System.Threading.Tasks;

namespace FirebaseAuth;

public class Function : ICloudEventFunction<AuthEventData>
{
    private readonly ILogger _logger;

    public Function(ILogger<Function> logger) =>
        _logger = logger;

    public Task HandleAsync(CloudEvent cloudEvent, AuthEventData data, CancellationToken cancellationToken)
    {
        _logger.LogInformation("Function triggered by change to user: {uid}", data.Uid);
        if (data.Metadata is UserMetadata metadata)
        {
            _logger.LogInformation("User created at: {created:s}", metadata.CreateTime.ToDateTimeOffset());
        }
        if (!string.IsNullOrEmpty(data.Email))
        {
            _logger.LogInformation("Email: {email}", data.Email);
        }

        // In this example, we don't need to perform any asynchronous operations, so the
        // method doesn't need to be declared async.
        return Task.CompletedTask;
    }
}

Ruby

require "functions_framework"

# Triggered by creation or deletion of a Firebase Auth user object.
FunctionsFramework.cloud_event "hello_auth" do |event|
  # Event-triggered Ruby functions receive a CloudEvents::Event::V1 object.
  # See https://cloudevents.github.io/sdk-ruby/latest/CloudEvents/Event/V1.html
  # The Firebase event payload can be obtained from the `data` field.
  payload = event.data

  logger.info "Function triggered by creation/deletion of user: #{payload['uid']}"
  logger.info "Created at: #{payload['metadata']['createdAt']}"
  logger.info "Email: #{payload['email']}" if payload.key? "email"
end

PHP

use Google\CloudFunctions\CloudEvent;

function firebaseAuth(CloudEvent $cloudevent)
{
    $log = fopen(getenv('LOGGER_OUTPUT') ?: 'php://stderr', 'wb');
    $data = $cloudevent->getData();

    fwrite(
        $log,
        'Function triggered by change to user: ' . $data['uid'] . PHP_EOL
    );
    fwrite($log, 'Created at: ' . $data['metadata']['createTime'] . PHP_EOL);

    if (isset($data['email'])) {
        fwrite($log, 'Email: ' . $data['email'] . PHP_EOL);
    }
}

פריסת הפונקציה

כדי לפרוס את הפונקציה, צריך לציין את סוג האירוע ואת הפרויקט שבו הגדרתם את Firebase Auth. במסוף Google Cloud , יש שדה יחיד לסוג האירוע, כי ההנחה היא שהפרויקט זהה לפרויקט שמכיל את הפונקציה.

עם זאת, בשורת הפקודה צריך להשתמש במחרוזות ספציפיות כדי לציין את שני הפרמטרים האלה. הפקודה gcloud הבאה פורסת פונקציה שמופעלת על ידי אירועים של משתמש create:

gcloud functions deploy FUNCTION_NAME \
  --no-gen2 \
  --entry-point ENTRY_POINT \
  --trigger-event providers/firebase.auth/eventTypes/user.create \
  --trigger-resource YOUR_PROJECT_ID \
  --runtime RUNTIME
ארגומנט תיאור
FUNCTION_NAME השם הרשום של פונקציות Cloud Run שאתם פורסים. זה יכול להיות שם של פונקציה בקוד המקור, או מחרוזת שרירותית. אם FUNCTION_NAME היא מחרוזת שרירותית, צריך לכלול את הדגל --entry-point.
--entry-point ENTRY_POINT השם של פונקציה או מחלקה בקוד המקור. אופציונלי, אלא אם לא השתמשתם ב-FUNCTION_NAME כדי לציין את הפונקציה בקוד המקור שתופעל במהלך הפריסה. במקרה כזה, צריך להשתמש ב---entry-point כדי לציין את השם של הפונקציה שניתנת להרצה.
--trigger-event NAME השם של סוג האירוע שמפעיל את הפונקציה. במקרה כזה, הערך צריך להיות create או delete, כמו שמופיע למעלה.
--trigger-resource NAME מזהה הפרויקט (בדוגמה הזו, YOUR_PROJECT_ID) של הפרויקט שמכיל את הפונקציה ואת האימות ב-Firebase.
--runtime RUNTIME שם זמן הריצה שבו אתם משתמשים. רשימה מלאה זמינה בחומר העזר בנושא gcloud.