Firebase 인증 트리거

Cloud Run Functions는 함수와 동일한 Google Cloud 프로젝트에서 Firebase 인증의 이벤트에 의해 트리거될 수 있습니다. 이러한 이벤트에는 사용자 생성과 사용자 삭제가 포함됩니다. 예를 들어 앱에 방금 계정을 만든 사용자에게 환영 이메일을 보낼 수 있습니다.

이벤트 유형

Firebase 인증은 사용자 createdelete 이벤트에 대한 응답으로 함수를 트리거할 수 있습니다.

이벤트 유형 트리거
providers/firebase.auth/eventTypes/user.create 사용자 계정이 생성되면 트리거됩니다.
providers/firebase.auth/eventTypes/user.delete 사용자 계정이 삭제되면 트리거됩니다.

사용자 생성

Firebase 계정은 다음과 같은 경우에 Cloud Run Functions의 사용자 생성 이벤트를 트리거합니다.

  • 사용자가 이메일 계정과 비밀번호를 만들 때

  • 사용자가 제휴 ID 공급업체를 통해 처음으로 로그인할 때

  • 개발자가 Firebase Admin SDK를 사용하여 계정을 생성할 때

  • 사용자가 새 익명 인증 세션에 처음으로 로그인할 때

사용자 삭제

사용자 삭제 시 트리거되도록 함수를 구성할 수도 있습니다.

이벤트 구조

이벤트 데이터는 UserRecord 객체로 제공됩니다.

비밀번호 기반 계정 생성 이벤트의 예시는 다음과 같습니다.

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

이 객체의 일부 속성은 특정 인증 방법을 사용할 때만 정의됩니다. 예를 들어, 비밀번호 기반 계정 이벤트는 사용자의 이메일 주소가 포함된 email 속성을 정의합니다. uid 속성(프로젝트에 대해 고유한 사용자 ID 포함)은 항상 정의됩니다.

샘플 코드

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
}

자바

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 인증을 구성한 프로젝트와 이벤트 유형을 지정해야 합니다. Google Cloud Console에는 프로젝트가 함수가 포함된 프로젝트와 동일한 것으로 간주되므로 이벤트 유형에 대한 단일 필드가 있습니다.

단, 명령줄에서 특정 문자열을 사용하여 이러한 두 매개변수를 지정해야 합니다. 다음 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 Functions의 등록된 이름입니다. 소스 코드의 함수 이름 또는 임의의 문자열일 수 있습니다. FUNCTION_NAME이 임의의 문자열이면 --entry-point 플래그를 포함해야 합니다.
--entry-point ENTRY_POINT 소스 코드의 함수 또는 클래스 이름입니다. FUNCTION_NAME을 사용하여 배포 중에 실행할 소스 코드에 함수를 지정하지 않은 경우 선택사항입니다. 이러한 경우 --entry-point를 사용하여 실행 가능한 함수의 이름을 제공해야 합니다.
--trigger-event NAME 함수를 트리거하는 이벤트 유형 이름입니다. 이 경우, 위에 나열된 것처럼 생성 또는 삭제 중 하나여야 합니다.
--trigger-resource NAME 함수와 Firebase 인증을 포함하는 프로젝트에 대한 프로젝트ID(이 예시에서는 YOUR_PROJECT_ID)입니다.
--runtime RUNTIME 사용 중인 런타임 이름입니다. 전체 목록은 gcloud 참조에서 확인할 수 있습니다.