Skip to content

Commit 4c4ccaf

Browse files
Surface push registration errors instead of failing silently
When pushIntegrationName is invalid, the registerDeviceToken API call previously failed silently. This change implements the onTokenRegistrationFailed callback in both iOS and Android native modules to log errors and emit events that JS code can listen to. Fixes #469 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e69c305 commit 4c4ccaf

5 files changed

Lines changed: 62 additions & 1 deletion

File tree

android/src/main/java/com/iterable/reactnative/RNIterableAPIModuleImpl.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,20 @@ public void onTokenRegistrationSuccessful(String authToken) {
681681
sendEvent(EventName.handleAuthSuccessCalled.name(), null);
682682
}
683683

684+
@Override
685+
public void onTokenRegistrationFailed(String reason) {
686+
String failureReason = reason != null ? reason : "unknown reason";
687+
IterableLogger.e(TAG, "Push token registration failed: " + failureReason);
688+
JSONObject eventDataJson = new JSONObject();
689+
try {
690+
eventDataJson.put("reason", failureReason);
691+
WritableMap eventData = Serialization.convertJsonToMap(eventDataJson);
692+
sendEvent(EventName.handleTokenRegistrationFailedCalled.name(), eventData);
693+
} catch (JSONException e) {
694+
IterableLogger.e(TAG, "Failed to send token registration failure event");
695+
}
696+
}
697+
684698
public void addListener(String eventName) {
685699
// Keep: Required for RN built in Event Emitter Calls.
686700
}
@@ -811,5 +825,6 @@ enum EventName {
811825
handleInAppCalled,
812826
handleUrlCalled,
813827
receivedIterableEmbeddedMessagesChanged,
814-
receivedIterableInboxChanged
828+
receivedIterableInboxChanged,
829+
handleTokenRegistrationFailedCalled
815830
}

ios/RNIterableAPI/ReactIterableAPI.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff 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,14 @@ extension ReactIterableAPI: IterableAuthDelegate {
818819
}
819820

820821
public func onTokenRegistrationFailed(_ reason: String?) {
822+
let failureReason = reason ?? "unknown reason"
823+
ITBError("Push token registration failed: \(failureReason)")
824+
guard shouldEmit else {
825+
return
826+
}
827+
delegate?.sendEvent(
828+
withName: EventName.handleTokenRegistrationFailedCalled.rawValue,
829+
body: ["reason": failureReason] as [String: Any])
821830
}
822831
}
823832

src/core/classes/Iterable.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff 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,19 @@ export class Iterable {
11091112
);
11101113
}
11111114
}
1115+
1116+
// Always listen for token registration failures so they are surfaced
1117+
RNEventEmitter.addListener(
1118+
IterableEventName.handleTokenRegistrationFailedCalled,
1119+
(dict: { reason: string }) => {
1120+
IterableLogger?.log(
1121+
'Push token registration failed: ' + (dict?.reason ?? 'unknown reason')
1122+
);
1123+
Iterable.savedConfig.onTokenRegistrationFailed?.(
1124+
dict?.reason ?? 'unknown reason'
1125+
);
1126+
}
1127+
);
11121128
}
11131129

11141130
/**

src/core/classes/IterableConfig.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,25 @@ export class IterableConfig {
375375
*/
376376
onEmbeddedMessagingDisabled?: () => void;
377377

378+
/**
379+
* A callback function that is called when device token registration fails.
380+
*
381+
* This can happen when the pushIntegrationName is invalid or when the
382+
* registerDeviceToken API call fails for any reason.
383+
*
384+
* @param reason - A string describing why the registration failed.
385+
*
386+
* @example
387+
* ```typescript
388+
* const config = new IterableConfig();
389+
* config.onTokenRegistrationFailed = (reason) => {
390+
* console.error('Push registration failed:', reason);
391+
* };
392+
* Iterable.initialize('<YOUR_API_KEY>', config);
393+
* ```
394+
*/
395+
onTokenRegistrationFailed?: (reason: string) => void;
396+
378397
/**
379398
* Converts the IterableConfig instance to a dictionary object.
380399
*

src/core/enums/IterableEventName.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff 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 */
27+
handleTokenRegistrationFailedCalled = 'handleTokenRegistrationFailedCalled',
2628
}

0 commit comments

Comments
 (0)