NestJS Notification Architecture
Priority: P0 (Standard)
Implement a "Dual-Write" notification system: persist to Database (In-App) and send via FCM (Push).
Workflow: Send a Notification
- Save to database — Persist the notification entity with type enum and metadata.
- Check FCM token — Verify the recipient has a valid
fcmToken; skip push if missing. - Send push — Call FCM inside
try/catch; never let FCM failure block the request. - Serialize data — Convert Dates to ISO strings; keep FCM
datapayload flat (IDs only).
Dual-Write Service Example
Structure
Implementation Guidelines
- Use Dual-Write: Save to DB first, then attempt FCM. Catch FCM errors so they don't block the logic.
- Define Granular Types: Use
NotificationTypeEnum (e.g.,APPOINTMENT_REMINDER) for frontend icon/color logic. - Stringify Metadata: Store routing data (IDs) as JSON string in DB, but Map to string-only Key-Values for FCM
data. - Handle Tokens: Check for
fcmTokenexistence before sending. Fail gracefully if missing. - Serialize Dates: Convert Dates to ISO strings before sending to FCM.
Anti-Patterns
- No Generic Types: Avoid
type: string. Always use the Enum. - No Blocking FCM: Never
awaitFCM without atry/catch. It shouldn't crash the request. - No Complex Data in Push: Keep FCM
datapayload flat and minimal (IDs only). Fetch details on open.