Skip to content

Commit 9a71665

Browse files
jaeoptclaude
andcommitted
[FSSDK-12670] Include commonIdentifiers when counting identifiers in identifyUser
identifyUser() was checking identifier count before augmenting with commonIdentifiers (e.g., vuid set by android-sdk), causing valid identify events with fs_user_id + vuid to be dropped as single-identifier. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 8812751 commit 9a71665

2 files changed

Lines changed: 32 additions & 2 deletions

File tree

core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,18 @@ public void identifyUser(@Nonnull Map<String, String> identifiers) {
151151
}
152152
}
153153

154+
// android-sdk sets vuid in commonIdentifiers. Augment here so the vuid is included
155+
// when counting identifiers. Idempotent with augment in sendEvent.
156+
Map<String, String> allIdentifiers = augmentCommonIdentifiers(validIdentifiers);
157+
154158
// An identify event requires at least 2 identifiers to link (e.g., vuid + fs_user_id).
155159
// A single identifier has no cross-reference value and would generate unnecessary traffic.
156-
if (validIdentifiers.size() < 2) {
160+
if (allIdentifiers.size() < 2) {
157161
logger.debug("ODP identify event is not dispatched (fewer than 2 valid identifiers).");
158162
return;
159163
}
160164

161-
ODPEvent event = new ODPEvent("fullstack", "identified", validIdentifiers, null);
165+
ODPEvent event = new ODPEvent("fullstack", "identified", allIdentifiers, null);
162166
sendEvent(event);
163167
}
164168

core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,32 @@ public void identifyUserSkippedWithEmptyMap() throws InterruptedException {
357357
logbackVerifier.expectMessage(Level.DEBUG, "ODP identify event is not dispatched (fewer than 2 valid identifiers).");
358358
}
359359

360+
@Test
361+
public void identifyUserSendsWhenCommonIdentifiersProvideSecondIdentifier() throws InterruptedException {
362+
ODPEventManager eventManager = spy(new ODPEventManager(mockApiManager));
363+
ArgumentCaptor<ODPEvent> captor = ArgumentCaptor.forClass(ODPEvent.class);
364+
365+
// VUID is set as a common identifier (e.g., vuid enabled in ODPManager)
366+
Map<String, String> commonIdentifiers = new HashMap<>();
367+
commonIdentifiers.put("vuid", "vuid_abc123");
368+
eventManager.setUserCommonIdentifiers(commonIdentifiers);
369+
370+
// createUserContext passes only fs_user_id — a single identifier in the call
371+
Map<String, String> identifiers = new HashMap<>();
372+
identifiers.put("fs_user_id", "test-user");
373+
eventManager.identifyUser(identifiers);
374+
375+
// Should NOT be dropped: common identifiers provide the second identifier (vuid),
376+
// making this a valid identify event with 2 identifiers total.
377+
verify(eventManager, times(1)).sendEvent(captor.capture());
378+
379+
ODPEvent event = captor.getValue();
380+
Map<String, String> eventIdentifiers = event.getIdentifiers();
381+
assertEquals(2, eventIdentifiers.size());
382+
assertEquals("test-user", eventIdentifiers.get("fs_user_id"));
383+
assertEquals("vuid_abc123", eventIdentifiers.get("vuid"));
384+
}
385+
360386
@Test
361387
public void identifyUserSendsWithThreeIdentifiers() throws InterruptedException {
362388
ODPEventManager eventManager = spy(new ODPEventManager(mockApiManager));

0 commit comments

Comments
 (0)