Skip to content

Commit 08cef24

Browse files
[SDK-289] Fixed double callback problem for setEmail with auto push registration (#985)
Fix for residual setEmailCallbackHandler after invoking it. Clearing failure and success setEmail callback after invocation. Better messaging on local success for setEmail and setRead
1 parent 4321a42 commit 08cef24

4 files changed

Lines changed: 51 additions & 2 deletions

File tree

iterableapi/src/main/java/com/iterable/iterableapi/IterableApi.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,14 +444,16 @@ private void completeUserLogin(@Nullable String email, @Nullable String userId,
444444
IterableLogger.w(TAG, "Cannot complete user login - JWT auth enabled but no validated authToken present");
445445
if (_setUserFailureCallbackHandler != null) {
446446
_setUserFailureCallbackHandler.onFailure("JWT authentication is enabled but no valid authToken is available", null);
447+
resetCallbackHandlers();
447448
}
448449
return;
449450
}
450451

451452
if (config.autoPushRegistration) {
452453
registerForPush();
453454
} else if (_setUserSuccessCallbackHandler != null) {
454-
_setUserSuccessCallbackHandler.onSuccess(new JSONObject()); // passing blank json object here as onSuccess is @Nonnull
455+
_setUserSuccessCallbackHandler.onSuccess(IterableResponse.setEmailLocalSuccessResponse);
456+
resetCallbackHandlers();
455457
}
456458

457459
getInAppManager().syncInApp();
@@ -747,6 +749,7 @@ private IterableHelper.SuccessHandler getSuccessHandler() {
747749

748750
if (originalSuccessHandler != null) {
749751
originalSuccessHandler.onSuccess(data);
752+
resetCallbackHandlers();
750753
}
751754
};
752755
}
@@ -762,11 +765,17 @@ private IterableHelper.FailureHandler getFailureHandler() {
762765

763766
if (originalFailureHandler != null) {
764767
originalFailureHandler.onFailure(reason, data);
768+
resetCallbackHandlers();
765769
}
766770
};
767771
}
768772
return wrappedFailureHandler;
769773
}
774+
775+
private void resetCallbackHandlers() {
776+
_setUserFailureCallbackHandler = null;
777+
_setUserSuccessCallbackHandler = null;
778+
}
770779
//endregion
771780

772781
//region SDK initialization

iterableapi/src/main/java/com/iterable/iterableapi/IterableHelper.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
import org.json.JSONObject;
88

9+
import java.util.Map;
10+
911
/**
1012
* Created by David Truong dt@iterable.com
1113
*/
@@ -33,4 +35,10 @@ public interface FailureHandler {
3335
public interface SuccessAuthHandler {
3436
void onSuccess(@NonNull String authToken);
3537
}
38+
}
39+
40+
class IterableResponse {
41+
static final JSONObject setEmailLocalSuccessResponse = new JSONObject(Map.of("message", "setEmail was completed locally."));
42+
43+
static final JSONObject setReadLocalSuccessResponse = new JSONObject(Map.of("message", "setRead was completed locally."));
3644
}

iterableapi/src/main/java/com/iterable/iterableapi/IterableInAppManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public synchronized void setRead(@NonNull IterableInAppMessage message, boolean
140140
public synchronized void setRead(@NonNull IterableInAppMessage message, boolean read, @Nullable IterableHelper.SuccessHandler successHandler, @Nullable IterableHelper.FailureHandler failureHandler) {
141141
message.setRead(read);
142142
if (successHandler != null) {
143-
successHandler.onSuccess(new JSONObject()); // passing blank json object here as onSuccess is @Nonnull
143+
successHandler.onSuccess(IterableResponse.setReadLocalSuccessResponse);
144144
}
145145
notifyOnChange();
146146
}

iterableapi/src/test/java/com/iterable/iterableapi/IterableApiTest.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1199,4 +1199,36 @@ public void testRegisterDeviceTokenIntegration_ConsentLoggingNotTriggeredWhenDis
11991199

12001200
//endregion
12011201

1202+
@Test
1203+
public void testSetEmailWithCallbackAndManualRegisterDeviceToken_NoDoubleCallback() throws Exception {
1204+
// Setup: Mock server responses
1205+
server.enqueue(new MockResponse().setResponseCode(200).setBody("{}"));
1206+
1207+
IterableConfig config = new IterableConfig.Builder()
1208+
.setAutoPushRegistration(false)
1209+
.setPushIntegrationName("testIntegration")
1210+
.build();
1211+
1212+
IterableApi.initialize(getContext(), "apiKey", config);
1213+
1214+
IterableHelper.SuccessHandler successHandler = mock(IterableHelper.SuccessHandler.class);
1215+
1216+
IterableApi.getInstance().setEmail("test@example.com", successHandler, null);
1217+
1218+
verify(successHandler, times(1)).onSuccess(any(JSONObject.class));
1219+
1220+
IterableApi.getInstance().registerDeviceToken("test_token");
1221+
1222+
Thread.sleep(200);
1223+
shadowOf(getMainLooper()).idle();
1224+
1225+
verify(successHandler, times(1)).onSuccess(any(JSONObject.class));
1226+
1227+
RecordedRequest registerRequest = server.takeRequest(1, TimeUnit.SECONDS);
1228+
assertNotNull("Should have made registerDeviceToken request", registerRequest);
1229+
assertTrue("Should be registerDeviceToken endpoint", registerRequest.getPath().contains("registerDeviceToken"));
1230+
}
1231+
1232+
//endregion
1233+
12021234
}

0 commit comments

Comments
 (0)