-
Notifications
You must be signed in to change notification settings - Fork 1
Push Notification System
This document provides a comprehensive technical overview of the server-side Push Notification System, detailing its value proposition, architectural flow, and resilience mechanisms.
The Push Notification System is engineered for flexibility, scalability, and high relevance, providing significant commercial and technical advantages.
-
Multi-Provider Support: The architecture is decoupled from any single push notification provider. It supports both Firebase Cloud Messaging (FCM) and OneSignal out-of-the-box. The active provider is determined by a single
primaryProviderkey in theRemoteConfig, allowing administrators to switch between services without a server redeployment. This avoids vendor lock-in and provides operational flexibility. -
Hyper-Targeted Notifications: The System moves beyond simple "all users" broadcasts. It enables users to create granular
SavedHeadlineFiltersubscriptions based on any combination of Topics, Sources, and Countries. When a "breaking news" event occurs, the System dispatches notifications only to users whose specific filter criteria match the event, dramatically increasing relevance and user engagement. -
In-App Notification Center: Every push notification sent is also persisted as an
InAppNotificationdocument in the database. This powers a client-side "inbox" or notification center, ensuring users can review important alerts they may have missed. These documents are automatically pruned after 90 days via a TTL index to manage data volume. -
Automated List Hygiene: The System includes a robust, automated cleanup mechanism. When a provider (FCM or OneSignal) reports a device token as invalid (e.g., the app was uninstalled), the corresponding
PushNotificationDevicedocument is automatically deleted from the database. This self-maintaining process improves delivery efficiency and keeps the device registry clean.
The system follows a precise, multi-stage process to deliver a breaking news notification from a headline trigger to a user's device.
-
Trigger & Configuration:
- The flow begins when
DefaultPushNotificationService.sendBreakingNewsNotificationis invoked with aHeadlineobject. - It immediately fetches the global
RemoteConfigto check ifpushNotifications.enabledistrueand if thebreakingOnlydelivery type is active. If not, the process aborts. - It identifies the
primaryProvider(e.g.,firebase) from the config.
- The flow begins when
-
Client Selection & Validation:
- The System selects the corresponding
IPushNotificationClient(FirebasePushNotificationClientorOneSignalPushNotificationClient). - A critical validation step ensures the selected client was successfully initialized (i.e., its API credentials were provided in the environment). If not, the process aborts with a severe error, preventing runtime failures.
- The System selects the corresponding
-
User & Criteria Matching:
- A paginated query is sent to the
user_content_preferencescollection to find all users with at least one filter subscribed tobreakingOnlynotifications. - The System then iterates through this list in-memory, applying the
_matchesCriterialogic. This function compares the incomingHeadlineagainst each of the user'sSavedHeadlineFilters. A filter matches if:- Its topic list is empty (wildcard) OR contains the headline's topic.
- Its source list is empty (wildcard) OR contains the headline's source.
- Its country list is empty (wildcard) OR contains the headline's event country.
- The result is a final set of
eligibleUserIds.
- A paginated query is sent to the
-
Device Fetching & Filtering:
- A single bulk query fetches all
PushNotificationDevicedocuments where theuserIdis in theeligibleUserIdsset. - This device list is further filtered to include only those that have a registered token for the system's
primaryProvider.
- A single bulk query fetches all
-
Payload Preparation & Persistence:
- The System constructs a
PushNotificationPayloadfrom the headline's data. It intelligently omits Base64-encoded images to avoid exceeding payload size limits. - For each eligible user, a unique
InAppNotificationdocument is created and persisted to the database. This operation happens in parallel for all users.
- The System constructs a
-
Dispatch & Cleanup:
- The System dispatches all notifications in parallel using the selected client's
sendBulkNotificationsmethod. - A
then()callback is attached to each send operation. Upon completion, this callback triggers the_cleanupInvalidDevicesmethod in a fire-and-forget manner, passing along any tokens the provider reported as invalid. - The cleanup method finds the corresponding device documents and deletes them.
- The System dispatches all notifications in parallel using the selected client's
The System is designed with multiple layers of resilience to ensure stable and predictable operation.
-
Configuration-Driven Abortion: The System aborts gracefully at the earliest possible stage if the feature is disabled via
RemoteConfig, preventing unnecessary database queries. -
Client Initialization Check: A hard check prevents the System from attempting to use a push notification client that failed to initialize due to missing credentials, avoiding runtime
nullexceptions. -
Graceful Empty-Set Handling: The flow includes explicit checks for empty results at every major step (no subscribers, no matching users, no registered devices). In each case, it logs an informative message and aborts cleanly.
-
Provider-Specific Batching: The
FirebasePushNotificationClientandOneSignalPushNotificationClientare aware of their respective API limits. They automatically chunk large lists of device tokens into batches of the appropriate size (500 for FCM, 2000 for OneSignal) to ensure reliable delivery. -
Invalid Token Pruning: The automated cleanup of invalid tokens is a key resilience feature. By removing stale registrations, the system reduces noise in future send operations and maintains a high-quality device list.
-
Error Isolation: The use of
Future.waitwith individualcatchErrorhandlers in theFirebasePushNotificationClientensures that the failure of a single notification send does not halt an entire batch. In the main System, the cleanup process is unawaited (fire-and-forget) so that any potential failure in deleting a token does not impact the primary notification workflow.
For comprehensive details regarding licensing, including trial and commercial options for the entire toolkit, please refer to the toolkit organization page.