Skip to content

Commit 8a36790

Browse files
authored
Merge pull request #65 from Iterable/bugfix/MOB-48-disableDevice-fix
[MOB-48] Pass email & userId to registerDeviceToken/disableToken calls to avoid concurrency issues
2 parents c50bf9c + f128e75 commit 8a36790

File tree

5 files changed

+58
-28
lines changed

5 files changed

+58
-28
lines changed

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

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,10 @@ public void registerDeviceToken(String applicationName, String token) {
519519
*/
520520
@Deprecated
521521
public void registerDeviceToken(final String applicationName, final String token, final String pushServicePlatform) {
522+
registerDeviceToken(_email, _userId, applicationName, token, pushServicePlatform);
523+
}
524+
525+
protected void registerDeviceToken(final String email, final String userId, final String applicationName, final String token, final String pushServicePlatform) {
522526
if (!IterableConstants.MESSAGING_PLATFORM_FIREBASE.equals(pushServicePlatform)) {
523527
IterableLogger.e(TAG, "registerDeviceToken: only MESSAGING_PLATFORM_FIREBASE is supported.");
524528
return;
@@ -527,7 +531,7 @@ public void registerDeviceToken(final String applicationName, final String token
527531
if (token != null) {
528532
final Thread registrationThread = new Thread(new Runnable() {
529533
public void run() {
530-
registerDeviceToken(applicationName, token, IterableConstants.MESSAGING_PLATFORM_FIREBASE, null);
534+
registerDeviceToken(email, userId, applicationName, token, IterableConstants.MESSAGING_PLATFORM_FIREBASE, null);
531535
}
532536
});
533537

@@ -770,7 +774,7 @@ public void registerForPush() {
770774
return;
771775
}
772776

773-
IterablePushRegistrationData data = new IterablePushRegistrationData(config.pushIntegrationName, IterablePushRegistrationData.PushRegistrationAction.ENABLE);
777+
IterablePushRegistrationData data = new IterablePushRegistrationData(_email, _userId, config.pushIntegrationName, IterablePushRegistrationData.PushRegistrationAction.ENABLE);
774778
new IterablePushRegistration().execute(data);
775779
}
776780

@@ -801,7 +805,7 @@ public void registerForPush(String pushIntegrationName, String projectNumber, St
801805
return;
802806
}
803807

804-
IterablePushRegistrationData data = new IterablePushRegistrationData(pushIntegrationName, projectNumber, pushServicePlatform, IterablePushRegistrationData.PushRegistrationAction.ENABLE);
808+
IterablePushRegistrationData data = new IterablePushRegistrationData(_email, _userId, pushIntegrationName, projectNumber, pushServicePlatform, IterablePushRegistrationData.PushRegistrationAction.ENABLE);
805809
new IterablePushRegistration().execute(data);
806810
}
807811

@@ -813,7 +817,7 @@ public void registerForPush(String pushIntegrationName, String projectNumber, St
813817
*/
814818
@Deprecated
815819
public void registerForPush(String pushIntegrationName) {
816-
IterablePushRegistrationData data = new IterablePushRegistrationData(pushIntegrationName, IterablePushRegistrationData.PushRegistrationAction.ENABLE);
820+
IterablePushRegistrationData data = new IterablePushRegistrationData(_email, _userId, pushIntegrationName, IterablePushRegistrationData.PushRegistrationAction.ENABLE);
817821
new IterablePushRegistration().execute(data);
818822
}
819823

@@ -826,7 +830,7 @@ public void disablePush() {
826830
return;
827831
}
828832

829-
IterablePushRegistrationData data = new IterablePushRegistrationData(config.pushIntegrationName, IterablePushRegistrationData.PushRegistrationAction.DISABLE);
833+
IterablePushRegistrationData data = new IterablePushRegistrationData(_email, _userId, config.pushIntegrationName, IterablePushRegistrationData.PushRegistrationAction.DISABLE);
830834
new IterablePushRegistration().execute(data);
831835
}
832836

@@ -857,7 +861,7 @@ public void disablePush(String iterableAppId, String projectNumber, String pushS
857861
return;
858862
}
859863

860-
IterablePushRegistrationData data = new IterablePushRegistrationData(iterableAppId, projectNumber, pushServicePlatform, IterablePushRegistrationData.PushRegistrationAction.DISABLE);
864+
IterablePushRegistrationData data = new IterablePushRegistrationData(_email, _userId, iterableAppId, projectNumber, pushServicePlatform, IterablePushRegistrationData.PushRegistrationAction.DISABLE);
861865
new IterablePushRegistration().execute(data);
862866
}
863867

@@ -1111,19 +1115,23 @@ protected void trackPushOpen(int campaignId, int templateId, String messageId, J
11111115
}
11121116
}
11131117

1114-
protected void disableToken(String token) {
1115-
disableToken(token, null, null);
1118+
protected void disableToken(String email, String userId, String token) {
1119+
disableToken(email, userId, token, null, null);
11161120
}
11171121

11181122
/**
11191123
* Internal api call made from IterablePushRegistration after a registrationToken is obtained.
11201124
* @param token
11211125
*/
1122-
protected void disableToken(String token, IterableHelper.SuccessHandler onSuccess, IterableHelper.FailureHandler onFailure) {
1126+
protected void disableToken(String email, String userId, String token, IterableHelper.SuccessHandler onSuccess, IterableHelper.FailureHandler onFailure) {
11231127
JSONObject requestJSON = new JSONObject();
11241128
try {
11251129
requestJSON.put(IterableConstants.KEY_TOKEN, token);
1126-
addEmailOrUserIdToJson(requestJSON);
1130+
if (email != null) {
1131+
requestJSON.put(IterableConstants.KEY_EMAIL, email);
1132+
} else {
1133+
requestJSON.put(IterableConstants.KEY_USER_ID, userId);
1134+
}
11271135

11281136
sendPostRequest(IterableConstants.ENDPOINT_DISABLE_DEVICE, requestJSON, onSuccess, onFailure);
11291137
}
@@ -1139,7 +1147,7 @@ protected void disableToken(String token, IterableHelper.SuccessHandler onSucces
11391147
* @param pushServicePlatform
11401148
* @param dataFields
11411149
*/
1142-
protected void registerDeviceToken(String applicationName, String token, String pushServicePlatform, JSONObject dataFields) {
1150+
protected void registerDeviceToken(String email, String userId, String applicationName, String token, String pushServicePlatform, JSONObject dataFields) {
11431151
if (!checkSDKInitialization()) {
11441152
return;
11451153
}

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,31 @@
1313
*/
1414
class IterablePushRegistration extends AsyncTask<IterablePushRegistrationData, Void, Void> {
1515
static final String TAG = "IterablePushRegistration";
16+
IterablePushRegistrationData iterablePushRegistrationData;
1617

1718
/**
1819
* Registers or disables the device
1920
*
2021
* @param params Push registration request data
2122
*/
2223
protected Void doInBackground(IterablePushRegistrationData... params) {
23-
IterablePushRegistrationData iterablePushRegistrationData = params[0];
24+
iterablePushRegistrationData = params[0];
2425
if (iterablePushRegistrationData.pushIntegrationName != null) {
2526
PushRegistrationObject pushRegistrationObject = getDeviceToken();
2627
if (pushRegistrationObject != null) {
2728
if (iterablePushRegistrationData.pushRegistrationAction == IterablePushRegistrationData.PushRegistrationAction.ENABLE) {
28-
IterableApi.sharedInstance.registerDeviceToken(iterablePushRegistrationData.pushIntegrationName, pushRegistrationObject.token);
29+
IterableApi.sharedInstance.registerDeviceToken(
30+
iterablePushRegistrationData.email,
31+
iterablePushRegistrationData.userId,
32+
iterablePushRegistrationData.pushIntegrationName,
33+
pushRegistrationObject.token,
34+
IterableConstants.MESSAGING_PLATFORM_FIREBASE);
35+
2936
} else if (iterablePushRegistrationData.pushRegistrationAction == IterablePushRegistrationData.PushRegistrationAction.DISABLE) {
30-
IterableApi.sharedInstance.disableToken(pushRegistrationObject.token);
37+
IterableApi.sharedInstance.disableToken(
38+
iterablePushRegistrationData.email,
39+
iterablePushRegistrationData.userId,
40+
pushRegistrationObject.token);
3141
}
3242
disableOldDeviceIfNeeded();
3343
}
@@ -79,7 +89,7 @@ private void disableOldDeviceIfNeeded() {
7989

8090
// We disable the device on Iterable but keep the token
8191
if (oldToken != null) {
82-
IterableApi.sharedInstance.disableToken(oldToken, new IterableHelper.SuccessHandler() {
92+
IterableApi.sharedInstance.disableToken(iterablePushRegistrationData.email, iterablePushRegistrationData.userId, oldToken, new IterableHelper.SuccessHandler() {
8393
@Override
8494
public void onSuccess(JSONObject data) {
8595
sharedPref.edit().putBoolean(IterableConstants.SHARED_PREFS_FCM_MIGRATION_DONE_KEY, true).apply();

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,26 @@ public enum PushRegistrationAction {
1010
DISABLE
1111
}
1212

13+
String email;
14+
String userId;
1315
String pushIntegrationName;
1416
String projectNumber = "";
1517
String messagingPlatform = IterableConstants.MESSAGING_PLATFORM_FIREBASE;
1618
PushRegistrationAction pushRegistrationAction;
1719

1820

19-
public IterablePushRegistrationData(String pushIntegrationName, String projectNumber, String messagingPlatform, PushRegistrationAction pushRegistrationAction){
21+
public IterablePushRegistrationData(String email, String userId, String pushIntegrationName, String projectNumber, String messagingPlatform, PushRegistrationAction pushRegistrationAction){
22+
this.email = email;
23+
this.userId = userId;
2024
this.pushIntegrationName = pushIntegrationName;
2125
this.projectNumber = projectNumber;
2226
this.messagingPlatform = messagingPlatform;
2327
this.pushRegistrationAction = pushRegistrationAction;
2428
}
2529

26-
public IterablePushRegistrationData(String pushIntegrationName, PushRegistrationAction pushRegistrationAction) {
30+
public IterablePushRegistrationData(String email, String userId, String pushIntegrationName, PushRegistrationAction pushRegistrationAction) {
31+
this.email = email;
32+
this.userId = userId;
2733
this.pushIntegrationName = pushIntegrationName;
2834
this.pushRegistrationAction = pushRegistrationAction;
2935
}

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import static org.mockito.ArgumentMatchers.any;
2121
import static org.mockito.ArgumentMatchers.eq;
22+
import static org.mockito.ArgumentMatchers.isNull;
2223
import static org.mockito.ArgumentMatchers.nullable;
2324
import static org.mockito.Mockito.mock;
2425
import static org.mockito.Mockito.never;
@@ -72,21 +73,22 @@ public void tearDown() throws Exception {
7273
public void testEnableDevice() throws Exception {
7374
when(mockInstanceId.getToken()).thenReturn(TEST_TOKEN);
7475

75-
IterablePushRegistrationData data = new IterablePushRegistrationData(INTEGRATION_NAME, IterablePushRegistrationData.PushRegistrationAction.ENABLE);
76+
IterablePushRegistrationData data = new IterablePushRegistrationData(IterableTestUtils.userEmail, null, INTEGRATION_NAME, IterablePushRegistrationData.PushRegistrationAction.ENABLE);
7677
new IterablePushRegistration().execute(data);
7778

78-
verify(apiMock, timeout(100)).registerDeviceToken(eq(INTEGRATION_NAME), eq(TEST_TOKEN));
79-
verify(apiMock, never()).disableToken(any(String.class), nullable(IterableHelper.SuccessHandler.class), nullable(IterableHelper.FailureHandler.class));
79+
verify(apiMock, timeout(100)).registerDeviceToken(eq(IterableTestUtils.userEmail), nullable(String.class), eq(INTEGRATION_NAME), eq(TEST_TOKEN), eq(IterableConstants.MESSAGING_PLATFORM_FIREBASE));
80+
verify(apiMock, never()).disableToken(eq(IterableTestUtils.userEmail), nullable(String.class), any(String.class), nullable(IterableHelper.SuccessHandler.class), nullable(IterableHelper.FailureHandler.class));
8081
}
8182

8283
@Test
8384
public void testDisableDevice() throws Exception {
8485
when(mockInstanceId.getToken()).thenReturn("testToken");
8586

86-
IterablePushRegistrationData data = new IterablePushRegistrationData(INTEGRATION_NAME, IterablePushRegistrationData.PushRegistrationAction.DISABLE);
87+
IterablePushRegistrationData data = new IterablePushRegistrationData(IterableTestUtils.userEmail, null, INTEGRATION_NAME, IterablePushRegistrationData.PushRegistrationAction.DISABLE);
8788
new IterablePushRegistration().execute(data);
89+
ShadowApplication.runBackgroundTasks();
8890

89-
verify(apiMock, timeout(100)).disableToken(eq(TEST_TOKEN));
91+
verify(apiMock, timeout(100)).disableToken(eq(IterableTestUtils.userEmail), isNull(String.class), eq(TEST_TOKEN));
9092
}
9193

9294
@Test
@@ -96,20 +98,20 @@ public void testDisableOldGcmToken() throws Exception {
9698
when(mockInstanceId.getToken()).thenReturn(NEW_TOKEN);
9799
when(mockInstanceId.getToken(eq(GCM_SENDER_ID), eq(IterableConstants.MESSAGING_PLATFORM_GOOGLE))).thenReturn(OLD_TOKEN);
98100

99-
IterablePushRegistrationData data = new IterablePushRegistrationData(INTEGRATION_NAME, IterablePushRegistrationData.PushRegistrationAction.ENABLE);
101+
IterablePushRegistrationData data = new IterablePushRegistrationData(IterableTestUtils.userEmail, null, INTEGRATION_NAME, IterablePushRegistrationData.PushRegistrationAction.ENABLE);
100102
new IterablePushRegistration().execute(data);
101103
ShadowApplication.runBackgroundTasks();
102104

103105
ArgumentCaptor<IterableHelper.SuccessHandler> successHandlerCaptor = ArgumentCaptor.forClass(IterableHelper.SuccessHandler.class);
104-
verify(apiMock).registerDeviceToken(eq(INTEGRATION_NAME), eq(NEW_TOKEN));
105-
verify(apiMock, times(1)).disableToken(eq(OLD_TOKEN), successHandlerCaptor.capture(), nullable(IterableHelper.FailureHandler.class));
106+
verify(apiMock).registerDeviceToken(eq(IterableTestUtils.userEmail), isNull(String.class), eq(INTEGRATION_NAME), eq(NEW_TOKEN), eq(IterableConstants.MESSAGING_PLATFORM_FIREBASE));
107+
verify(apiMock, times(1)).disableToken(eq(IterableTestUtils.userEmail), isNull(String.class), eq(OLD_TOKEN), successHandlerCaptor.capture(), nullable(IterableHelper.FailureHandler.class));
106108
successHandlerCaptor.getValue().onSuccess(new JSONObject());
107109

108110
reset(apiMock);
109111

110112
new IterablePushRegistration().execute(data);
111-
verify(apiMock).registerDeviceToken(eq(INTEGRATION_NAME), eq(NEW_TOKEN));
112-
verify(apiMock, never()).disableToken(any(String.class), nullable(IterableHelper.SuccessHandler.class), nullable(IterableHelper.FailureHandler.class));
113+
verify(apiMock).registerDeviceToken(eq(IterableTestUtils.userEmail), isNull(String.class), eq(INTEGRATION_NAME), eq(NEW_TOKEN), eq(IterableConstants.MESSAGING_PLATFORM_FIREBASE));
114+
verify(apiMock, never()).disableToken(eq(IterableTestUtils.userEmail), isNull(String.class), any(String.class), nullable(IterableHelper.SuccessHandler.class), nullable(IterableHelper.FailureHandler.class));
113115
}
114116

115117
}

iterableapi/src/test/java/com/iterable/iterableapi/unit/IterableTestUtils.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@
1717
import java.util.Map;
1818

1919
public class IterableTestUtils {
20+
public static final String apiKey = "fake_key";
21+
public static final String userEmail = "test_email";
22+
23+
2024
public static void createIterableApi() {
21-
IterableApi.sharedInstanceWithApiKey(RuntimeEnvironment.application, "fake_key", "test_email");
25+
IterableApi.sharedInstanceWithApiKey(RuntimeEnvironment.application, apiKey, userEmail);
2226
}
2327

2428
public static String getResourceString(String fileName) throws IOException {

0 commit comments

Comments
 (0)