File tree Expand file tree Collapse file tree
android/src/main/java/com/iterable/reactnative Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -681,6 +681,19 @@ public void onTokenRegistrationSuccessful(String authToken) {
681681 sendEvent (EventName .handleAuthSuccessCalled .name (), null );
682682 }
683683
684+ @ Override
685+ public void onTokenRegistrationFailed (String reason ) {
686+ IterableLogger .e (TAG , "Token registration failed: " + reason );
687+ JSONObject reasonJson = new JSONObject ();
688+ try {
689+ reasonJson .put ("reason" , reason != null ? reason : "unknown" );
690+ WritableMap eventData = Serialization .convertJsonToMap (reasonJson );
691+ sendEvent (EventName .handleTokenRegistrationFailedCalled .name (), eventData );
692+ } catch (JSONException e ) {
693+ IterableLogger .e (TAG , "Failed to send token registration failure event" );
694+ }
695+ }
696+
684697 public void addListener (String eventName ) {
685698 // Keep: Required for RN built in Event Emitter Calls.
686699 }
@@ -811,5 +824,6 @@ enum EventName {
811824 handleInAppCalled ,
812825 handleUrlCalled ,
813826 receivedIterableEmbeddedMessagesChanged ,
814- receivedIterableInboxChanged
827+ receivedIterableInboxChanged ,
828+ handleTokenRegistrationFailedCalled
815829}
Original file line number Diff line number Diff line change @@ -35,6 +35,7 @@ import React
3535 case handleAuthFailureCalled
3636 case handleEmbeddedMessageUpdateCalled
3737 case handleEmbeddedMessagingDisabledCalled
38+ case handleTokenRegistrationFailedCalled
3839 }
3940
4041 @objc public static var supportedEvents : [ String ] {
@@ -818,6 +819,13 @@ extension ReactIterableAPI: IterableAuthDelegate {
818819 }
819820
820821 public func onTokenRegistrationFailed( _ reason: String ? ) {
822+ ITBError ( " Token registration failed: \( reason ?? " unknown reason " ) " )
823+ guard shouldEmit else {
824+ return
825+ }
826+ delegate? . sendEvent (
827+ withName: EventName . handleTokenRegistrationFailedCalled. rawValue,
828+ body: [ " reason " : reason ?? " unknown " ] as [ String : Any ] )
821829 }
822830}
823831
Original file line number Diff line number Diff line change @@ -956,6 +956,9 @@ export class Iterable {
956956 RNEventEmitter . removeAllListeners (
957957 IterableEventName . handleEmbeddedMessagingDisabledCalled
958958 ) ;
959+ RNEventEmitter . removeAllListeners (
960+ IterableEventName . handleTokenRegistrationFailedCalled
961+ ) ;
959962 }
960963
961964 /**
@@ -1109,6 +1112,25 @@ export class Iterable {
11091112 ) ;
11101113 }
11111114 }
1115+
1116+ // Always listen for token registration failures so they are surfaced
1117+ // to developers. Without this, push registration errors (e.g. invalid
1118+ // pushIntegrationName) are silently swallowed.
1119+ RNEventEmitter . addListener (
1120+ IterableEventName . handleTokenRegistrationFailedCalled ,
1121+ ( dict : { reason : string } ) => {
1122+ const reason = dict ?. reason ?? 'unknown' ;
1123+
1124+ // Always log to console.error so developers can see the failure
1125+ // even without the callback configured
1126+ console . error (
1127+ `[Iterable] Push token registration failed: ${ reason } . ` +
1128+ 'Check that pushIntegrationName in your IterableConfig is valid.'
1129+ ) ;
1130+
1131+ Iterable . savedConfig . onTokenRegistrationFailed ?.( reason ) ;
1132+ }
1133+ ) ;
11121134 }
11131135
11141136 /**
Original file line number Diff line number Diff line change @@ -375,6 +375,28 @@ export class IterableConfig {
375375 */
376376 onEmbeddedMessagingDisabled ?: ( ) => void ;
377377
378+ /**
379+ * A callback function that is called when push token registration fails.
380+ *
381+ * This can happen when `pushIntegrationName` is set to an invalid value,
382+ * or when the `/api/users/registerDeviceToken` endpoint returns an error.
383+ *
384+ * Without this callback, push registration errors are silently ignored,
385+ * making it difficult to diagnose push notification setup issues.
386+ *
387+ * @param reason - A string describing why token registration failed.
388+ *
389+ * @example
390+ * ```typescript
391+ * const config = new IterableConfig();
392+ * config.onTokenRegistrationFailed = (reason) => {
393+ * console.error('Push token registration failed:', reason);
394+ * };
395+ * Iterable.initialize('<YOUR_API_KEY>', config);
396+ * ```
397+ */
398+ onTokenRegistrationFailed ?: ( reason : string ) => void ;
399+
378400 /**
379401 * Converts the IterableConfig instance to a dictionary object.
380402 *
Original file line number Diff line number Diff line change @@ -23,4 +23,6 @@ export enum IterableEventName {
2323 handleEmbeddedMessageUpdateCalled = 'handleEmbeddedMessageUpdateCalled' ,
2424 /** Event that fires when embedded messaging is disabled */
2525 handleEmbeddedMessagingDisabledCalled = 'handleEmbeddedMessagingDisabledCalled' ,
26+ /** Event that fires when push token registration fails (e.g., invalid pushIntegrationName) */
27+ handleTokenRegistrationFailedCalled = 'handleTokenRegistrationFailedCalled' ,
2628}
You can’t perform that action at this time.
0 commit comments