Skip to content

Conversation

@kdawgwilk
Copy link

@kdawgwilk kdawgwilk commented Nov 5, 2025

Description

Adds v2 identity.onUserCreated / identity.onUserDeleted CloudEvent triggers that mirror the v1 auth user lifecycle handlers, including shared user-record construction and exported types for parity. Updates unit coverage to validate endpoint metadata and user payload hydration.

Code sample

import { onUserCreated, onUserDeleted } from "firebase-functions/v2/identity";

export const welcomeNewUser = onUserCreated((event) => {
  const user = event.data;
  // ...handle new account...
});

export const cleanupRemovedUser = onUserDeleted(async (event) => {
  const user = event.data;
  // ...perform cleanup...
});

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @kdawgwilk, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces the long-awaited v2 versions of Firebase Authentication user lifecycle triggers, "onUserCreated" and "onUserDeleted". By providing these new CloudEvent-based functions, developers can now leverage the modern v2 functions framework to react to user creation and deletion events, ensuring consistency and feature parity with existing v1 handlers. The changes include robust type definitions and thorough testing to guarantee reliable event processing and user data hydration.

Highlights

  • New Auth Triggers: Added new "identity.onUserCreated" and "identity.onUserDeleted" CloudEvent triggers for Firebase Authentication user lifecycle events.
  • Feature Parity: Ensured feature parity with v1 auth user lifecycle handlers, including shared user-record construction and exported types for consistency.
  • Unit Test Coverage: Implemented comprehensive unit tests to validate endpoint metadata and proper hydration of user payloads for the new triggers.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds v2 CloudEvent triggers for identity.onUserCreated and identity.onUserDeleted, mirroring the v1 user lifecycle handlers. The implementation is clean and reuses logic effectively through a shared onUserOperation function. The associated unit tests cover the new functionality, but I've suggested an improvement to the onUserDeleted test to ensure it also validates the event payload hydration, similar to the onUserCreated test.

Comment on lines +136 to +149
it("should accept a handler", () => {
const fn = identity.onUserDeleted(() => null);

expect(fn.__endpoint).to.deep.equal({
...MINIMAL_V2_ENDPOINT,
platform: "gcfv2",
labels: {},
eventTrigger: {
eventType: identity.userDeletedEvent,
eventFilters: {},
retry: false,
},
});
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The test for onUserDeleted only verifies the endpoint configuration. To improve test coverage and ensure the data transformation logic is correct for this trigger, this test should be made async and include assertions to check that the handler receives the correctly hydrated user data. This would align it with the more comprehensive test for onUserCreated.

    it("should accept a handler", async () => {
      let received: identity.UserRecord | undefined;
      const fn = identity.onUserDeleted((event) => {
        received = event.data;
        return null;
      });

      expect(fn.__endpoint).to.deep.equal({
        ...MINIMAL_V2_ENDPOINT,
        platform: "gcfv2",
        labels: {},
        eventTrigger: {
          eventType: identity.userDeletedEvent,
          eventFilters: {},
          retry: false,
        },
      });

      const rawEvent = {
        specversion: "1.0" as const,
        id: "event-id",
        source: "//identitytoolkit.googleapis.com/projects/project-id",
        type: identity.userDeletedEvent,
        time: new Date().toISOString(),
        data: {
          uid: "abc123",
          metadata: {
            creationTime: "2016-12-15T19:37:37.059Z",
            lastSignInTime: "2017-01-01T00:00:00.000Z",
          },
        },
      };

      await fn(rawEvent as any);
      expect(received).to.exist;
      expect(received!.uid).to.equal("abc123");
      expect(received!.metadata).to.be.instanceof(identity.UserRecordMetadata);
    });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant