ARTICLE AD BOX
I'm building a Node.js backend using Drizzle and Firebase Cloud Messaging to send push notifications. Users can have multiple devices.
Currently, my notification flow works like this:
I want to send a notification to a list of userIds.
I query the DB to get all FCM tokens for those users:
.where(inArray(userDevices.userId, usersIds));I send the batch to Firebase.
If Firebase returns retryable errors (e.g., network issues, internal server errors) for specific tokens, I map those failed tokens back to their userIds.
I schedule a retry job (using pg-boss) passing the array of failed userIds.
I realized this flow causes duplicate notifications. If User A has two devices (Token 1 and Token 2), and Token 1 fails while Token 2 succeeds, my system schedules a retry for User A. When the retry job runs, it fetches all tokens for User A from the database again, and sends the notification to both Token 1 and Token 2. Token 2 ends up receiving the notification twice. I could just use the failed tokens to reschedule the job but what if in the mean time the user logs out and the token is invalid? I still would want to query the DB to ensure the token is valid.
Is passing the failed tokens to the background job the best practice to handle FCM retries?
How should i change the flow?
