I am migrating some Firebase Functions code from 1st to 2nd gen. In my 1st gen functions I am using a shouldDropEvent
helper which looks at the timestamp of the context and decides to drop the event after it has been retried for x minutes.
For 2nd gen I do not know where to find this timestamp.
Also, I would like to configure the retry behaviour, but I don't think it's possible with the current API.
The pubSendNotificationToUserToken
is an abstraction I use for pubsub that keeps the topic and handler colocated in one place. Please ignore it.
import { pubSendNotificationToUserToken } from "@repo/core/notifications";
import type { EventContext } from "firebase-functions";
import functions from "firebase-functions";
import { onMessagePublished } from "firebase-functions/v2/pubsub";
const MINUTE_MS = 60 * 1000;
export const retryEventMaxAgeMs = 20 * MINUTE_MS;
export const sendNotificationToUserToken_1stGen = functions
.runWith({
failurePolicy: true,
})
.pubsub.topic(pubSendNotificationToUserToken.topic)
.onPublish(async (message, context) => {
if (shouldDropEvent(context, MINUTE_MS * 5)) {
return;
}
await pubSendNotificationToUserToken.handle(message.json);
});
export const sendNotificationToUserToken_2ndGen = onMessagePublished(
{
topic: pubSendNotificationToUserToken.topic,
retry: true,
},
async (event) => {
await pubSendNotificationToUserToken.handle(event.data.message.json);
}
);
/**
* Check if max age has been reached. Timestamp should be in RFC 3339 format to
* match cloud functions context event timestamp.
*/
function shouldDropEvent(
context: EventContext<unknown>,
maxAgeMs = retryEventMaxAgeMs
) {
const eventAge = Date.now() - Date.parse(context.timestamp);
if (eventAge > maxAgeMs) {
console.error(
new Error(
`Dropping event ${context.eventType} for ${context.resource.name} because max age was reached.`
)
);
return true;
}
return false;
}
The onMessagePublished event handler receives a single CloudEvent typed argument which has a time attribute.
export const sendNotificationToUserToken_2ndGen = onMessagePublished(
{
topic: pubSendNotificationToUserToken.topic,
retry: true,
},
async (event) => {
// event.time contains the time of the CloudEvent argument
}
);