diff --git a/kits/firestore-bigquery-export/README.md b/kits/firestore-bigquery-export/README.md index 8ffb4e27d..02b2d827c 100644 --- a/kits/firestore-bigquery-export/README.md +++ b/kits/firestore-bigquery-export/README.md @@ -155,10 +155,12 @@ the instances cannot collide. ## Events When `EVENTARC_CHANNEL` is configured, the function publishes `onStart` and -`onError` lifecycle events under -`firebase.extensions.firestore-bigquery-export.v1.*`. The extension's -`onSuccess` event is not published; see the events entry under -"Differences from the Stream Firestore to BigQuery extension" below. +`onError` lifecycle events. Each one is published twice, under +`firebase.extensions.firestore-bigquery-export.v1.*` and under the legacy +`firebase.extensions.firestore-counter.v1.*` type the extension also used, so +triggers written against either type keep firing. The extension's `onSuccess` +event is not published; see the events entry under "Differences from the Stream +Firestore to BigQuery extension" below. ## Provisioning @@ -252,11 +254,12 @@ queue in the console, and the two knobs that tuned that queue, queue handler, which is gone, so the kit publishes `onStart` and `onError` only. -Events are published under `firebase.extensions.firestore-bigquery-export.v1.*` -only. The extension also published a duplicate copy of every event under -`firebase.extensions.firestore-counter.v1.*`, a historical naming mistake kept -for backwards compatibility. If you have Eventarc triggers listening on those -`firestore-counter` types, point them at the `firestore-bigquery-export` types. +Every event is still published twice, once under +`firebase.extensions.firestore-bigquery-export.v1.*` and once under +`firebase.extensions.firestore-counter.v1.*`. The `firestore-counter` type is a +historical naming mistake the extension kept for backwards compatibility, and +the kit keeps it for the same reason: triggers listening on it survive the +migration. Write new triggers against the `firestore-bigquery-export` types. ### Wildcard columns include the document ID diff --git a/kits/firestore-bigquery-export/src/events.ts b/kits/firestore-bigquery-export/src/events.ts index baa9fc03c..f03b2a8eb 100644 --- a/kits/firestore-bigquery-export/src/events.ts +++ b/kits/firestore-bigquery-export/src/events.ts @@ -18,13 +18,17 @@ import * as eventArc from "firebase-admin/eventarc"; const { getEventarc } = eventArc; /** - * Builds the Eventarc event type for this extension. + * Generates both the OLD and NEW event types to maintain backward compatibility. + * + * Old Event Type: firebase.extensions.firestore-counter.v1.{eventName} + * New Event Type: firebase.extensions.firestore-bigquery-export.v1.{eventName} * * @param eventName The name of the event (e.g., "onStart", "onError", etc.) - * @returns The event type string. + * @returns An array containing both the old and new event types */ const getEventTypes = (eventName: string) => [ - `firebase.extensions.firestore-bigquery-export.v1.${eventName}`, + `firebase.extensions.firestore-counter.v1.${eventName}`, // OLD Event Type for backward compatibility + `firebase.extensions.firestore-bigquery-export.v1.${eventName}`, // NEW Event Type following the updated convention ]; let eventChannel: eventArc.Channel | undefined; diff --git a/kits/firestore-bigquery-export/tests/events.test.ts b/kits/firestore-bigquery-export/tests/events.test.ts index 35057e463..18c77cde8 100644 --- a/kits/firestore-bigquery-export/tests/events.test.ts +++ b/kits/firestore-bigquery-export/tests/events.test.ts @@ -59,14 +59,13 @@ describe("channel configured", () => { setupEventChannel(); }); - test("publishes the firestore-bigquery-export event type only", async () => { + test("publishes both the legacy and the current event type", async () => { await recordStartEvent({ a: 1 }); - expect(publish).toHaveBeenCalledTimes(1); - expect(publish).toHaveBeenCalledWith( - expect.objectContaining({ - type: "firebase.extensions.firestore-bigquery-export.v1.onStart", - }) - ); + expect(publish).toHaveBeenCalledTimes(2); + expect(publish.mock.calls.map((c) => c[0].type)).toEqual([ + "firebase.extensions.firestore-counter.v1.onStart", + "firebase.extensions.firestore-bigquery-export.v1.onStart", + ]); }); test("error / success / completion map to their event types", async () => { @@ -76,9 +75,24 @@ describe("channel configured", () => { const types = publish.mock.calls.map((c) => c[0].type); expect(types).toEqual([ + "firebase.extensions.firestore-counter.v1.onError", "firebase.extensions.firestore-bigquery-export.v1.onError", + "firebase.extensions.firestore-counter.v1.onSuccess", "firebase.extensions.firestore-bigquery-export.v1.onSuccess", + "firebase.extensions.firestore-counter.v1.onCompletion", "firebase.extensions.firestore-bigquery-export.v1.onCompletion", ]); }); + + test("the legacy copy carries the same payload as the current one", async () => { + await recordErrorEvent(new Error("boom"), "doc1"); + + const [legacy, current] = publish.mock.calls.map((c) => c[0]); + expect(legacy.data).toEqual({ message: "boom" }); + expect(legacy.subject).toBe("doc1"); + expect({ ...legacy, type: undefined }).toEqual({ + ...current, + type: undefined, + }); + }); });