React Native Notify Kit

repository·main·Indexed 41 days ago

https://github.com/marcocrupi/react-native-notify-kit

A community-maintained fork of Notifee designed for modern React Native (New Architecture/TurboModules) and Expo CNG development builds. It provides advanced notification capabilities including Android foreground services, rich styles, and progress bars. Includes a server-side FCM message builder for Node.js 22+ to construct payloads compatible with the client-side handler.

Tokens
141.4K
Snippets
421
Records
586
Agent score
41%

What's inside React Native Notify Kit

  1. Overview of iOS Notification Features

    main

    Notify Kit provides comprehensive support for the following iOS-specific notification capabilities:

    • Appearance: Customize how notifications are visually presented to users.
    • Badges: Manage the application icon badge count.
    • Behaviour: Control the delivery and display behavior of notifications.
    • Categories & Actions: Define notification categories to enable interactive buttons (actions).
    • Interaction: Handle user taps on notifications and execution of quick actions.
    • Permissions: Manage the request and granting of notification permissions from users.
    • Remote Notification Support: Integrate with remote push notification services.
  2. Overview of Android Notification Features

    main

    Notify Kit integrates with the latest Android API features while providing backwards compatibility for older devices (down to Android 4.4W / API 20). The library allows for rich, styled, and highly interactive notifications.

    Key customization areas include:

    • Appearance: Icons, colors, and visibility.
    • Behaviour: Sound, vibration, and lights.
    • Channels & Groups: Organizing notifications so users can control handling preferences.
    • Foreground Service: Displaying prominent notifications for long-running background tasks.
    • Grouping & Sorting: Managing related notifications in the notification pane.
    • Interaction: Adding actions for users to interact with the app directly from the notification.
    • Permissions: Checking notification status for the app, channel groups, or specific channels.
    • Progress Indicators: Showing and updating progress for ongoing tasks.
    • Styles: Using expandable images, text, or message conversations.
    • Timers: Displaying counting timers for tasks like phone calls or remaining event time.
  3. Overview of react-native-notify-kit

    main

    What is react-native-notify-kit?

    react-native-notify-kit is a feature-rich local notification library for React Native (Android and iOS). It is a maintained fork of invertase/notifee specifically designed for the React Native New Architecture (React Native 0.73+).

    Key Features

    • Local Notifications: Core API for managing local notifications on both platforms.
    • FCM Mode: A first-class, layered integration for Firebase Cloud Messaging (FCM).
    • Server SDK: A zero-dependency server SDK (react-native-notify-kit/server) for building notification payloads.
    • CLI Scaffolding: A CLI tool to automatically scaffold the iOS Notification Service Extension.

    Platform Support

    Because Android and iOS handle notifications differently, the library provides platform-specific implementations. Developers should refer to specific guides for iOS and Android to understand platform-specific behaviors and configurations.

  4. Compare NotifyKit FCM Mode with other notification solutions

    main

    NotifyKit FCM Mode is designed to provide high reliability for iOS background notifications by using an NSE (Notification Service Extension) to convert data-only FCM pushes into APNs alerts. This achieves ~99% reliability on iOS compared to the ~40-70% reliability of standard data-only silent pushes used in manual @notifee + RNFB setups.

    Key advantages include:

    • iOS Reliability: Uses APNs alerts via NSE.
    • Setup: Supports Expo config plugins or bare React Native CLI.
    • Backend: Provides a zero-dependency Node.js SDK (react-native-notify-kit/server) that can run on any environment (Lambda, Cloud Functions, etc.).
    • Styling: Supports full NotifyKit features like BIG_TEXT, BIG_PICTURE, actions, attachments, and categories.
    • Cost: Leverages FCM's free tier with no monthly active device limits.
  5. Understand the benefits of the react-native-notify-kit fork

    main

    This project is a fork of the original Notifee library that includes critical bug fixes for both iOS and Android. Key improvements include:

    • iOS: Fixed issues with remote notification tap handlers (improving compatibility with React Native Firebase), getInitialNotification() returning null on cold starts, and completionHandler lifecycle issues.
    • Android: Fixed issues with scheduled notifications being lost after device reboots (especially on OEM devices like Xiaomi, OnePlus, etc.), improved handling of SCHEDULE_EXACT_ALARM denials, and resolved crashes in foreground services on Android 14+.
    • General: Improved API symmetry between iOS and Android for methods like getDisplayedNotifications() and EventType.DELIVERED.
  6. What is Notify Kit FCM Mode and when to use it

    main

    FCM Mode is a delivery pattern designed for apps that want react-native-notify-kit to be the sole display layer for FCM push notifications on both Android and iOS. It solves two primary issues:

    1. Android Duplicate Notifications: Prevents the OS from auto-displaying a notification when using notification payloads, which often results in two tray entries if the client also calls displayNotification.
    2. iOS Delivery Reliability: Avoids the high drop rates (30–60%) associated with "silent" (data-only) pushes on iOS by using an aps.alert payload combined with a Notification Service Extension (NSE).

    When to use FCM Mode

    • You use a Node.js backend (or Firebase Cloud Functions) and want a single library to manage display logic for both platforms.
    • You require consistent notification styles, channels, actions, and attachments across Android and iOS.
    • You need high iOS APNs delivery reliability without sacrificing client-side control over how notifications are presented.

    When NOT to use FCM Mode

    • If you only target one platform (Android or iOS).
    • If you are okay with the higher drop rates of iOS data-only pushes.
    • If you must use Expo Go (FCM Mode requires native modules/targets and is only supported via Expo CNG/development builds).
  7. How FCM Mode architecture works

    main

    FCM Mode uses an asymmetric payload strategy to achieve consistent behavior through a single developer API. The notifee_options blob is the core of this system; it is byte-identical on both platforms but placed in different locations within the FCM payload.

    Payload Distribution

    • Android: Uses a data-only payload. The notifee_options blob is located in data.notifee_options. The FCM SDK does not auto-display the notification. Instead, the app receives the message in setBackgroundMessageHandler or onMessage and calls notifee.handleFcmMessage(remoteMessage) to render it.
    • iOS: Uses an alert payload (aps.alert) with mutable-content: 1. The notifee_options blob is located in apns.payload.notifee_options. A Notification Service Extension (NSE) intercepts the push, reads the blob, and reshapes the notification (handling attachments, categories, etc.) before the OS displays it.

    Data Flow

    1. Backend: Calls buildNotifyKitPayload({ token, notification, options }) from react-native-notify-kit/server.
    2. FCM Service: Routes the platform-specific payload to the device.
    3. Android Client: setBackgroundMessageHandler $\rightarrow$ handleFcmMessage $\rightarrow$ displayNotification.
    4. iOS Client: APNs $\rightarrow$ NSE (NotifyKit-NSE.appex) $\rightarrow$ OS draws the enriched notification.
  8. Understand Notification Delivery Events on iOS

    main

    On iOS, the EventType.DELIVERED event is emitted to the onForegroundEvent handler whenever a Notify Kit-owned notification is presented to the user while the app is in the foreground. This applies to:

    • Local displayNotification calls.
    • Trigger notifications that fire while the app is in the foreground.
    • handleFcmMessage foreground displays.

    Important: Background or killed trigger notifications do not emit DELIVERED events on iOS.

  9. Understand FCM Mode limitations

    main

    iOS Background Event Gap

    On iOS, when a push arrives while the app is in the background or killed, the EventType.DELIVERED event is not emitted to onBackgroundEvent. This is because the NSE draws the notification and the main app process never wakes. To detect background delivery on iOS, check getDisplayedNotifications() when the app returns to the foreground.

    Payload Size

    The server SDK warns when payloads approach ~3500 bytes. To mitigate this:

    • Shorten the body.
    • Use Android BIG_TEXT style for long text.
    • Collapse nested data values into a single JSON string.
    • Use a "nudge-then-fetch" pattern (push an ID, then fetch the full payload when the app opens).

    Android Delivery Guarantees

    • Data-only delivery: Background/killed-state delivery depends on FCM priority, device state (Doze), and OEM policy. Use high priority for user-visible background validation.
    • Force-stop: Delivery is not guaranteed if the user performs a force-stop via system settings.
  10. Configure Trigger Notifications with AlarmManager

    main

    By default, react-native-notify-kit uses AlarmManager for trigger notifications to ensure reliability and exact timing, whereas upstream Notifee uses WorkManager. AlarmManager is better for time-sensitive notifications but uses more battery.

    To opt out and use battery-friendly WorkManager scheduling (where exact timing is not critical), set alarmManager: false in your trigger configuration.

    // Example trigger config to opt-out of AlarmManager
    await notifee.createTriggerNotification(
      {
        // ... other config
        alarmManager: false,
      },
      AndroidTriggerType.TIMESTAMP,
      new Date(Date.now() + 10000),
    );