@loyalytics/swan-react-native-sdk 2.5.1-beta.3 → 2.5.1-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -161,6 +161,7 @@ function _resetClickDedup() {
161
161
  class SwanSDK {
162
162
  listeners = {};
163
163
  coldStartCheckDone = false;
164
+ pendingNotificationPayload = null;
164
165
  SDK_VERSION = _version.SDK_VERSION;
165
166
  isProduction = 'STAGE';
166
167
  appId = '';
@@ -635,6 +636,15 @@ class SwanSDK {
635
636
  this.coldStartCheckDone = true;
636
637
  // Defer to next microtask so the listener is fully registered before events emit
637
638
  Promise.resolve().then(() => {
639
+ // Deliver buffered standard/image push notification (one-shot APIs like
640
+ // getInitialNotification() can't be re-read — data was buffered in emitNotificationOpened).
641
+ // Skip carousel notifications — checkPendingCarouselClick() handles those with per-item routes.
642
+ const payload = this.pendingNotificationPayload;
643
+ this.pendingNotificationPayload = null;
644
+ if (payload && payload.notificationType !== 'carousel') {
645
+ this.emitNotificationOpened(payload);
646
+ }
647
+ // Check for pending carousel click (native side holds data until consumed)
638
648
  this.checkPendingCarouselClick();
639
649
  });
640
650
  }
@@ -664,6 +674,15 @@ class SwanSDK {
664
674
  * @internal - Used by module-level notification handlers
665
675
  */
666
676
  emitNotificationOpened(payload) {
677
+ const listeners = this.listeners[SwanSDK.EVENTS.NOTIFICATION_OPENED];
678
+ if ((!listeners || listeners.length === 0) && !this.coldStartCheckDone) {
679
+ // Cold start: buffer for delivery when first listener registers.
680
+ // One-shot APIs like getInitialNotification() won't have this data later.
681
+ _Logger.default.log('[SwanSDK] Buffering notification payload for deferred delivery');
682
+ this.pendingNotificationPayload = payload;
683
+ return;
684
+ }
685
+ this.pendingNotificationPayload = null;
667
686
  this.emit(SwanSDK.EVENTS.NOTIFICATION_OPENED, payload);
668
687
  // Also emit unified deep link event for push source
669
688
  this.emitDeepLinkOpened({
@@ -2878,10 +2897,13 @@ class SwanSDK {
2878
2897
  // similar to how Firebase requires onMessage() at module level.
2879
2898
 
2880
2899
  // Check if app was opened by tapping a Notifee-displayed notification (data-only architecture)
2900
+ // Notifee's getInitialNotification() returns { notification, pressAction }.
2901
+ // The FCM data we stored via displayNotification({ data: {...} }) lives at
2902
+ // notification.data — NOT at the top-level .data (which doesn't exist).
2881
2903
  const initialNotification = await notifee.getInitialNotification();
2882
2904
  if (initialNotification && !this.initialNotificationHandled) {
2883
2905
  const messageId = initialNotification?.notification?.id;
2884
- const notificationData = initialNotification.data || {};
2906
+ const notificationData = initialNotification.notification?.data || {};
2885
2907
  if (messageId && markClickProcessed(messageId)) {
2886
2908
  _Logger.default.log('[SwanSDK] App opened from Notifee notification tap:', messageId);
2887
2909
  this.initialNotificationHandled = true;