Skip to content

Commit 70128dc

Browse files
committed
Implement Alias Functionality
New public APIs: - Identity.aliasUser(AliasRequest) - User.getFirstSeen() - User.getLastSeen() Changed APIs - identify/login/logout completion handler added a 3rd parameter, "previousUserId" (error, userId) -> (error, userId, previousUserId) - IdentityApiRequest.setOnUserAlias() has been deprecated. This method call has not been fully removed, but it's implementation was replaced with a stub
1 parent ca8359e commit 70128dc

File tree

19 files changed

+1080
-472
lines changed

19 files changed

+1080
-472
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,4 @@ npm-debug.log
7676
build
7777
.gradle
7878
local.properties
79+
package-lock.json

android/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ dependencies {
4747
//
4848
// (See https://github.com/mparticle/mparticle-android-sdk for the latest version)
4949
//
50-
compileOnly 'com.mparticle:android-core:5+'
50+
compileOnly 'com.mparticle:android-core:[5.9.3, )'
5151

5252
//
5353
// And, if you want to include kits, you can do so as follows:
@@ -58,6 +58,7 @@ dependencies {
5858
testImplementation 'org.mockito:mockito-android:2.18.3'
5959
testImplementation 'com.android.support:support-annotations:27.1.1'
6060
testImplementation 'junit:junit:4.12'
61+
testImplementation files('libs/java-json.jar')
6162

6263
testImplementation 'com.mparticle:android-core:5+'
6364
testImplementation 'com.facebook.react:react-native:+'

android/gradlew

100644100755
File mode changed.

android/libs/java-json.jar

82.7 KB
Binary file not shown.

android/src/main/java/com/mparticle/react/MParticleModule.java

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,15 @@
1919
import com.mparticle.commerce.Product;
2020
import com.mparticle.commerce.TransactionAttributes;
2121
import com.mparticle.commerce.Promotion;
22+
import com.mparticle.identity.AliasRequest;
23+
import com.mparticle.identity.IdentityApi;
2224
import com.mparticle.identity.IdentityApiRequest;
2325
import com.mparticle.identity.IdentityApiResult;
2426
import com.mparticle.identity.MParticleUser;
2527
import com.mparticle.identity.IdentityHttpResponse;
2628
import com.mparticle.identity.TaskFailureListener;
2729
import com.mparticle.identity.TaskSuccessListener;
30+
import com.mparticle.internal.Logger;
2831

2932
import java.util.ArrayList;
3033
import java.util.HashMap;
@@ -164,8 +167,13 @@ public void onFailure(IdentityHttpResponse identityHttpResponse) {
164167
public void onSuccess(IdentityApiResult identityApiResult) {
165168
//Continue with login, and you can also access the new/updated user:
166169
MParticleUser user = identityApiResult.getUser();
167-
String userID = Long.toString(user.getId());
168-
completion.invoke(null, userID);
170+
String userId = Long.toString(user.getId());
171+
MParticleUser previousUser = identityApiResult.getPreviousUser();
172+
String previousUserId = null;
173+
if (previousUser != null) {
174+
previousUserId = Long.toString(previousUser.getId());
175+
}
176+
completion.invoke(null, userId, previousUserId);
169177
}
170178
});
171179
}
@@ -227,6 +235,65 @@ public void getCurrentUserWithCompletion(Callback completion) {
227235

228236
}
229237

238+
@ReactMethod
239+
public void aliasUsers(final ReadableMap readableMap, final Callback completion) {
240+
IdentityApi identityApi = MParticle.getInstance().Identity();
241+
ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
242+
Long destinationMpid = null;
243+
Long sourceMpid = null;
244+
Long startTime = null;
245+
Long endTime = null;
246+
247+
while (iterator.hasNextKey()) {
248+
try {
249+
switch (iterator.nextKey()) {
250+
case "destinationMpid":
251+
destinationMpid = Utils.getLong(readableMap, "destinationMpid", false);
252+
break;
253+
case "sourceMpid":
254+
sourceMpid = Utils.getLong(readableMap, "sourceMpid", false);
255+
break;
256+
case "startTime":
257+
startTime = Utils.getLong(readableMap, "startTime", true);
258+
break;
259+
case "endTime":
260+
endTime = Utils.getLong(readableMap, "endTime", true);
261+
break;
262+
}
263+
} catch (NumberFormatException ex) {
264+
Logger.error(ex.getMessage());
265+
completion.invoke(false, ex.getMessage());
266+
return;
267+
}
268+
}
269+
if (startTime == null && endTime == null) {
270+
MParticleUser sourceUser = null;
271+
MParticleUser destinationUser = null;
272+
if (sourceMpid != null) {
273+
sourceUser = identityApi.getUser(sourceMpid);
274+
}
275+
if (destinationMpid != null) {
276+
destinationUser = identityApi.getUser(destinationMpid);
277+
}
278+
if (sourceUser != null && destinationUser != null) {
279+
AliasRequest request = AliasRequest.builder(sourceUser, destinationUser).build();
280+
boolean success = MParticle.getInstance().Identity().aliasUsers(request);
281+
completion.invoke(success);
282+
} else {
283+
completion.invoke(false, "MParticleUser could not be found for provided sourceMpid and destinationMpid");
284+
}
285+
} else {
286+
AliasRequest request = AliasRequest.builder()
287+
.destinationMpid(destinationMpid)
288+
.sourceMpid(sourceMpid)
289+
.startTime(startTime)
290+
.endTime(endTime)
291+
.build();
292+
boolean success = identityApi.aliasUsers(request);
293+
completion.invoke(success);
294+
}
295+
}
296+
230297
@ReactMethod
231298
public void getUserIdentities(final String userId, Callback completion) {
232299
MParticleUser selectedUser = MParticle.getInstance().Identity().getUser(parseMpid(userId));
@@ -237,6 +304,26 @@ public void getUserIdentities(final String userId, Callback completion) {
237304
}
238305
}
239306

307+
@ReactMethod
308+
public void getFirstSeen(final String userId, Callback completion) {
309+
MParticleUser selectedUser = MParticle.getInstance().Identity().getUser(Utils.parseMpid(userId));
310+
if (selectedUser != null) {
311+
completion.invoke(String.valueOf(selectedUser.getFirstSeenTime()));
312+
} else {
313+
completion.invoke();
314+
}
315+
}
316+
317+
@ReactMethod
318+
public void getLastSeen(final String userId, Callback completion) {
319+
MParticleUser selectedUser = MParticle.getInstance().Identity().getUser(Utils.parseMpid(userId));
320+
if (selectedUser != null) {
321+
completion.invoke(String.valueOf(selectedUser.getLastSeenTime()));
322+
} else {
323+
completion.invoke();
324+
}
325+
}
326+
240327
@ReactMethod
241328
public void getAttributions(Callback completion) {
242329
Map<Integer, AttributionResult> attributionResultMap = MParticle.getInstance().getAttributionResults();
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.mparticle.react;
2+
3+
import com.facebook.react.bridge.ReadableMap;
4+
5+
public class Utils {
6+
7+
public static long parseMpid(String longString) {
8+
try {
9+
return Long.parseLong(longString);
10+
} catch (NumberFormatException ex) {
11+
return 0L;
12+
}
13+
}
14+
15+
public static Long getLong(ReadableMap readableMap, String key, boolean allowLossy) {
16+
switch (readableMap.getType(key)) {
17+
case String:
18+
return Long.valueOf(readableMap.getString(key));
19+
case Number:
20+
if (allowLossy) {
21+
try {
22+
return Integer.valueOf(readableMap.getInt(key)).longValue();
23+
} catch (Exception ex) {
24+
return Double.valueOf(readableMap.getDouble(key)).longValue();
25+
}
26+
}
27+
break;
28+
case Null:
29+
return null;
30+
}
31+
throw new NumberFormatException("Expecting " + (allowLossy ? " Number or " : "") + "String representation of a Long. Received " + readableMap.getType(key));
32+
}
33+
34+
}

0 commit comments

Comments
 (0)