Repository navigation
9.3.0
Changed
-
Android:
pressActionnow defaults to{ id: 'default', launchActivity: 'default' }when omitted from the notification payload. Previously, notifications without an explicitpressActionwould display correctly but tapping them did nothing — a silent footgun, especially for trigger notifications where the "tap doesn't open app" symptom only manifested after an app kill (the internalNotificationReceiverActivitywould launch, post the stickyInitialNotificationEventto EventBus, and immediately finish, leaving the user with no app visible). Apps that intentionally want a non-tappable notification can passpressAction: nullexplicitly to opt out. Opt-out viapressAction: nullis implemented using a reserved sentinel id (__NOTIFEE_OPT_OUT__) at the TS→native boundary to survive Bundle serialization reliably. -
iOS: Behavior change —
EventType.DELIVEREDis now emitted toonForegroundEventfor all Notifee-owned notifications displayed while the app is in foreground, not just trigger notifications. Previously, the iOS implementation inwillPresentNotification:had aif (notifeeTrigger != nil)guard inherited from upstream Notifee that suppressed DELIVERED for notifications created viadisplayNotification()(immediate display, no trigger). The notification was shown to the user but no event was emitted, breaking analytics, badge counters, and any other code relying on a global DELIVERED listener. Android always emitted DELIVERED in both cases, so this also resolves a long-standing iOS/Android asymmetry. To avoid duplicate events, the DELIVERED emission indisplayNotification:withBlock:(which fires from theaddNotificationRequest:completion handler) is now gated to non-foreground states —willPresentNotification:handles the foreground case, and the completion handler handles background/inactive. Potential impact: apps that registeredonForegroundEventlisteners on iOS may now receive DELIVERED events they did not before (one perdisplayNotification()call while in foreground). If your handler does heavy work per DELIVERED event, audit it. There is no opt-out flag — the previous behavior was a bug, and the new behavior matches Android. Known limitation: trigger notifications that fire while the app is in background or killed still do not emit DELIVERED on iOS. This is a platform limitation —willPresentNotification:is only invoked when the app is in foreground, and iOS does not provide a delegate callback for trigger notifications presented by the system in background. Android does not have this limitation (it emits DELIVERED unconditionally fromdisplayNotification()for both immediate and trigger notifications). If you need delivery confirmation for background trigger notifications on iOS, check the notification's presence viagetDisplayedNotifications()after the app returns to foreground.
Fixed
-
Android: Fixed
NotificationManager.displayNotification()producing a tap-less PendingIntent whenpressActionis absent from the notification bundle. The native path now synthesizes the default press action bundle and routes through the samecreateLaunchActivityIntent(...)code path used for explicitpressActionpayloads — extending the defense-in-depth approach of 9.1.19 to the "pressAction entirely absent" case. Protects trigger notifications rehydrated from the Room database after reboot/kill, headless tasks, and any other code path that bypasses the TS validator. Known limitation: on pre-Android 12 devices, theReceiverServicecode path does not benefit from the native defense-in-depth synthesis — only the TS validator default applies. This affects trigger notifications stored in Room DB before the fix was deployed on devices running Android 11 and below. -
iOS: Fixed potential loss of notification events at cold start when the React Native bridge takes longer than 1 second to initialize. The previous implementation in
NotifeeCoreDelegateHolderused adispatch_after(1 sec)+dispatch_oncecombo to drain_pendingEvents(PRESS, DELIVERED, etc. emitted by iOS beforeNotifeeApiModulewas ready). On large apps or slow devices where the bridge init exceeded 1 second, the flush could run before the delegate was connected, and thedispatch_onceprevented any retry — events were permanently lost. The samedispatch_oncealso prevented re-flushing after a JS reload in dev mode, since the static token had already fired. Replaced with an event-driven synchronous flush triggered whensetDelegate:installs a valid delegate: pending events are drained in FIFO order immediately, and any future delegate re-assignment (JS reload) flushes again. The second-level buffer inNotifeeApiModule.pendingCoreEvents(drained bystartObserving) continues to handle the "delegate set but JS listeners not yet attached" window, so events are never dropped regardless of bridge or JS timing. Added@synchronized(self)around_pendingEventsmutations for thread safety. No public API change. -
iOS: Corrected error message in
validateIOSPermissions— the validator for thebadgefield threw"'alert' badge a boolean value."(wrong property name and ungrammatical) instead of"'badge' expected a boolean value.". Dev-only, surfaces only when passing a non-boolean torequestPermission({ badge }).
Removed
- Removed unused
.buckconfig(Buck is no longer used by React Native since 0.74; file was stale since 2019). - Removed unused
.flowconfig(project is TypeScript-only; Flow config was a leftover from the original Invertase fork). Verified no references inpackage.json, CI workflows, or scripts. - Android: Removed unused EventBus annotation processor (
org.greenrobot:eventbus-annotation-processor) and itseventBusIndexbuild option from the Gradle configuration. The generatedEventBusIndexclass was never referenced at runtime —EventBus.builder().build()is called without.addIndex(). This eliminates the confusing build warningThe following options were not recognized by any processor: '[eventBusIndex]'reported in some configurations. No functional change — EventBus runtime dependency is unchanged.
📦 npm: https://www.npmjs.com/package/react-native-notify-kit/v/9.3.0