-
Notifications
You must be signed in to change notification settings - Fork 384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(firestore-bigquery-export): Add Backward Compatibility and New Event Types for Firestore BigQuery Export #2244
base: next
Are you sure you want to change the base?
Conversation
aa614f5
to
925668e
Compare
/** | ||
* Generates both the OLD and NEW event types to maintain backward compatibility. | ||
* | ||
* Old Event Type: firebase.extensions.firestore-counter.v1.{eventName} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we should be publishing both, i think we probably want a breaking change here, @pr-Mais ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably yes, but should be documented well in the CHANGELOG
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
9ddae40
to
3fcac8e
Compare
- param: EXT_INSTANCE_ID | ||
label: Extension Instance ID | ||
description: >- | ||
What is the unique identifier for this instance of the extension? This ID | ||
ensures that multiple instances do not interfere with one another. It is | ||
set automatically by Firebase but can also be customized if required. | ||
required: true | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- param: EXT_INSTANCE_ID | |
label: Extension Instance ID | |
description: >- | |
What is the unique identifier for this instance of the extension? This ID | |
ensures that multiple instances do not interfere with one another. It is | |
set automatically by Firebase but can also be customized if required. | |
required: true |
Since other extensions don't use unique extension ID for the events, let's keep it consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this based on your previous comments regarding several instances of the same extension.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, after second thought we agreed on keeping the behaviour consistent with other extensions
*/ | ||
const getEventTypes = (eventName: string) => [ | ||
`firebase.extensions.firestore-counter.v1.${eventName}`, // OLD Event Type for backward compatibility | ||
`firebase.extensions.${EXTENSION_NAME}.v1.${eventName}`, // NEW Event Type following the updated convention |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`firebase.extensions.${EXTENSION_NAME}.v1.${eventName}`, // NEW Event Type following the updated convention | |
`firebase.extensions.firestore-bigquery-export.v1.${eventName}`, // NEW Event Type following the updated convention |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as before: I added this based on your previous comments regarding several instances of the same extension.
export const recordStartEvent = async (data: string | object) => { | ||
if (!eventChannel) return; | ||
if (!eventChannel) return Promise.resolve(); // Explicitly return a resolved Promise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!eventChannel) return Promise.resolve(); // Explicitly return a resolved Promise | |
if (!eventChannel) return Promise.resolve(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if there is no eventChannel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean? I just removed the comment, not needed as the return is self-explanatory.
export const recordErrorEvent = async (err: Error, subject?: string) => { | ||
if (!eventChannel) return; | ||
if (!eventChannel) return Promise.resolve(); // Ensure consistent return type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!eventChannel) return Promise.resolve(); // Ensure consistent return type | |
if (!eventChannel) return Promise.resolve(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if there is no eventChannel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry my bad.
export const recordSuccessEvent = async ({ | ||
subject, | ||
data, | ||
}: { | ||
subject: string; | ||
data: string | object; | ||
}) => { | ||
if (!eventChannel) return; | ||
if (!eventChannel) return Promise.resolve(); // Explicitly return a resolved Promise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!eventChannel) return Promise.resolve(); // Explicitly return a resolved Promise | |
if (!eventChannel) return Promise.resolve(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if there is no eventChannel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry my bad.
export const recordCompletionEvent = async (data: string | object) => { | ||
if (!eventChannel) return; | ||
if (!eventChannel) return Promise.resolve(); // Ensure consistent return type |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (!eventChannel) return Promise.resolve(); // Ensure consistent return type | |
if (!eventChannel) return Promise.resolve(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if there is no eventChannel?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This suggested change is just to remove the unnecessary code comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fyi - in an async
function, return;
is the same as return Promise.resolve()
.
It's implied by the async
keyword.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ts might complain about some difference between Promise<void>
and Promise<undefined>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry my bad.
3fcac8e
to
15cc2b0
Compare
15cc2b0
to
26951aa
Compare
#1981
Description (issue 1981):
This PR introduces backward-compatible event types while adding new naming conventions for Firestore BigQuery Export. The changes ensure robust event handling across multiple versions of the extension. The following updates have been made:
Key Changes:
1. New Event Types:
• Introduced new events using the updated naming convention:
• firebase.extensions.firestore-bigquery-export.v1.onStart
• firebase.extensions.firestore-bigquery-export.v1.onSuccess
• firebase.extensions.firestore-bigquery-export.v1.onError
• firebase.extensions.firestore-bigquery-export.v1.onCompletion
2. Backward Compatibility:
• Maintains the existing events under the old naming convention:
• firebase.extensions.firestore-counter.v1.*
• Both old and new event types are published for each operation to ensure smooth migration.
3. Refactored Event Publishing:
• Updated event publishing logic to dynamically handle both old and new event types.
• Functions now publish events using Promise.all for better concurrency.
4. Unit Tests:
• Enhanced unit tests to verify:
• Events for both old and new naming conventions are correctly published.
• Proper handling of CREATE, DELETE, and UPDATE scenarios.
• Mocked Eventarc interactions for improved testing reliability.
5. Code Improvements:
• Refactored events.ts to dynamically generate both old and new event types for reuse.
• Added extensive documentation to clarify the event publishing logic and backward compatibility strategy.