Skip to content

Commit 03e3b4a

Browse files
feat: array list and json array support to the user properties
1 parent 1083303 commit 03e3b4a

File tree

5 files changed

+40
-20
lines changed

5 files changed

+40
-20
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## XX.XX.XX
2-
* Added mixed type of immutable lists, arrays to client given segmentations
2+
* Added support for mixed type of immutable lists, arrays to client given segmentations and user properties.
3+
* Added array, list and JSONArray support to the user properties.
4+
35
* Mitigated issues where:
46
* session was ending regardless of manual control after without merge, not anymore.
57
* session was not starting even if consent is not required and automatic sessions are enabled after without merge, not anymore.

sdk/src/androidTest/java/ly/count/android/sdk/DeviceIdTests.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ public void sessionDurationScenario_1() throws InterruptedException {
303303
assertEquals(5, TestUtils.getCurrentRQ().length);
304304

305305
TestUtils.validateRequest("ff_merge", TestUtils.map("old_device_id", "1234"), 1);
306-
TestUtils.validateRequest("ff_merge", TestUtils.map("user_details", "{\"custom\":{\"prop2\":\"123\",\"prop1\":\"string\",\"prop3\":\"false\"}}"), 2);
306+
TestUtils.validateRequest("ff_merge", TestUtils.map("user_details", "{\"custom\":{\"prop2\":123,\"prop1\":\"string\",\"prop3\":false}}"), 2);
307307
ModuleSessionsTests.validateSessionEndRequest(3, 3, "ff_merge");
308308

309309
Thread.sleep(1000);
@@ -334,9 +334,9 @@ public void sessionDurationScenario_1() throws InterruptedException {
334334

335335
assertEquals(9, TestUtils.getCurrentRQ().length);
336336

337-
TestUtils.validateRequest("ff", TestUtils.map("user_details", "{\"custom\":{\"prop4\":\"[sd]\"}}"), 5);
338-
TestUtils.validateRequest("ff", TestUtils.map("user_details", "{\"custom\":{\"prop6\":\"{key=123}\",\"prop5\":\"{key=value}\",\"prop7\":\"{key=false}\"}}"), 6);
339-
TestUtils.validateRequest("ff", TestUtils.map("user_details", "{\"custom\":{\"prop2\":\"456\",\"prop1\":\"string_a\",\"prop3\":\"true\"}}"), 7);
337+
TestUtils.validateRequest("ff", TestUtils.map("user_details", "{\"custom\":{\"prop4\":[\"sd\"]}}"), 5);
338+
TestUtils.validateRequest("ff", TestUtils.map("user_details", "{\"custom\":{}}"), 6);
339+
TestUtils.validateRequest("ff", TestUtils.map("user_details", "{\"custom\":{\"prop2\":456,\"prop1\":\"string_a\",\"prop3\":true}}"), 7);
340340

341341
TestUtils.validateRequest("ff_merge", TestUtils.map("old_device_id", "ff"), 8);
342342
}

sdk/src/androidTest/java/ly/count/android/sdk/ModuleUserProfileTests.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ public void internalLimit_setProperties() throws JSONException {
514514
ModuleUserProfile.NAME_KEY, "name",
515515
ModuleUserProfile.PICTURE_KEY, "picture"
516516
), TestUtils.map(
517-
"cu", "23", // because in user profiles, all values are stored as strings
517+
"cu", 23, // because in user profiles, all values are stored as strings
518518
"ha", "black")
519519
);
520520
}
@@ -567,12 +567,11 @@ public void internalLimit_setProperties_maxValueSize() throws JSONException {
567567
ModuleUserProfile.PICTURE_KEY, "picture"
568568
), TestUtils.map(
569569
"custom1", "va", // because in user profiles, all values are stored as strings
570-
"custom2", "23",
570+
"custom2", 23,
571571
"hair", "bl",
572-
"custom3", "1234",
573-
"custom4", "1234.5",
574-
"custom5", "true",
575-
"custom6", obj.toString()) // toString() is called on non-String values
572+
"custom3", 1234,
573+
"custom4", 1234.5,
574+
"custom5", true)
576575
);
577576
}
578577

@@ -613,7 +612,7 @@ public void internalLimit_setProperties_maxSegmentationValues() throws JSONExcep
613612
Countly.sharedInstance().userProfile().setProperties(TestUtils.map("a", "b", "c", "d", "f", 5, "level", 45, "age", 101));
614613
Countly.sharedInstance().userProfile().save();
615614

616-
validateUserProfileRequest(TestUtils.map(), TestUtils.map("f", "5", "age", "101"));
615+
validateUserProfileRequest(TestUtils.map(), TestUtils.map("f", 5, "age", 101));
617616
}
618617

619618
/**

sdk/src/main/java/ly/count/android/sdk/ModuleUserProfile.java

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class ModuleUserProfile extends ModuleBase {
3232
String picture;
3333
static String picturePath;//protected only for testing
3434
String gender;
35-
Map<String, String> custom;
35+
Map<String, Object> custom;
3636
Map<String, JSONObject> customMods;
3737
int byear = 0;
3838

@@ -219,12 +219,15 @@ void modifyCustomData(String key, Object value, String mod) {
219219
return;
220220
}
221221

222-
Object truncatedValue;
222+
Object valueAdded;
223223
String truncatedKey = UtilsInternalLimits.truncateKeyLength(key, _cly.config_.sdkInternalLimits.maxKeyLength, _cly.L, "[ModuleUserProfile] modifyCustomData");
224224
if (value instanceof String) {
225-
truncatedValue = UtilsInternalLimits.truncateValueSize((String) value, _cly.config_.sdkInternalLimits.maxValueSize, _cly.L, "[ModuleUserProfile] modifyCustomData");
225+
valueAdded = UtilsInternalLimits.truncateValueSize((String) value, _cly.config_.sdkInternalLimits.maxValueSize, _cly.L, "[ModuleUserProfile] modifyCustomData");
226+
} else if (UtilsInternalLimits.isSupportedDataType(value)) {
227+
valueAdded = value;
226228
} else {
227-
truncatedValue = value;
229+
L.w("[ModuleUserProfile] modifyCustomData, provided an unsupported type for key: [" + key + "], value: [" + value + "], type: [" + value.getClass().getSimpleName() + "], mod: [" + mod + "], omitting call");
230+
return;
228231
}
229232

230233
if (customMods == null) {
@@ -234,14 +237,14 @@ void modifyCustomData(String key, Object value, String mod) {
234237
JSONObject ob;
235238
if (!mod.equals("$pull") && !mod.equals("$push") && !mod.equals("$addToSet")) {
236239
ob = new JSONObject();
237-
ob.put(mod, truncatedValue);
240+
ob.put(mod, valueAdded);
238241
} else {
239242
if (customMods.containsKey(truncatedKey)) {
240243
ob = customMods.get(truncatedKey);
241244
} else {
242245
ob = new JSONObject();
243246
}
244-
ob.accumulate(mod, truncatedValue);
247+
ob.accumulate(mod, valueAdded);
245248
}
246249
customMods.put(truncatedKey, ob);
247250
isSynced = false;
@@ -264,7 +267,7 @@ void setPropertiesInternal(@NonNull Map<String, Object> data) {
264267

265268
//todo recheck if in the future these can be <String, Object>
266269
Map<String, String> dataNamedFields = new HashMap<>();
267-
Map<String, String> dataCustomFields = new HashMap<>();
270+
Map<String, Object> dataCustomFields = new HashMap<>();
268271

269272
for (Map.Entry<String, Object> entry : data.entrySet()) {
270273
String key = entry.getKey();
@@ -297,7 +300,11 @@ void setPropertiesInternal(@NonNull Map<String, Object> data) {
297300

298301
if (!isNamed) {
299302
String truncatedKey = UtilsInternalLimits.truncateKeyLength(key, _cly.config_.sdkInternalLimits.maxKeyLength, _cly.L, "[ModuleUserProfile] setPropertiesInternal");
300-
dataCustomFields.put(truncatedKey, value.toString());
303+
if (UtilsInternalLimits.isSupportedDataType(value)) {
304+
dataCustomFields.put(truncatedKey, value);
305+
} else {
306+
L.w("[ModuleUserProfile] setPropertiesInternal, provided an unsupported type for key: [" + key + "], value: [" + value + "], type: [" + value.getClass().getSimpleName() + "], omitting call");
307+
}
301308
}
302309
}
303310

sdk/src/main/java/ly/count/android/sdk/UtilsInternalLimits.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,18 @@ private static boolean isSupportedDataTypeBasic(@Nullable Object value) {
351351
return value instanceof String || value instanceof Integer || value instanceof Double || value instanceof Boolean || value instanceof Float || value instanceof Long;
352352
}
353353

354+
/**
355+
* This function currently validates below segmentations:
356+
* - Event segmentations (custom ones not internal keys)
357+
* - Crash segmentations
358+
* - View segmentations
359+
* - User profile custom properties
360+
* - User profile custom properties modifiers
361+
* - Feedback widgets' results
362+
*
363+
* @param value to check
364+
* @return true if the value is a supported data type
365+
*/
354366
static boolean isSupportedDataType(@Nullable Object value) {
355367
if (isSupportedDataTypeBasic(value)) {
356368
return true;

0 commit comments

Comments
 (0)