Open
Conversation
Add a persistent $device_id that survives identify() and reset() calls, enabling stable device-level feature flag bucketing across identity changes. The device ID is seeded from the anonymous ID on first init and sent in /flags request payloads.
Contributor
posthog-android Compliance ReportDate: 2026-04-09 18:05:12 UTC ✅ All Tests Passed!0/0 tests passed |
marandaneto
reviewed
Apr 9, 2026
| getPreferences().setValue(DISTINCT_ID, value) | ||
| } | ||
|
|
||
| private fun initDeviceId() { |
Member
There was a problem hiding this comment.
doing the same as getDeviceId
should we just call getDeviceId instead?
marandaneto
reviewed
Apr 9, 2026
Comment on lines
+1308
to
+1317
| val deviceId = getPreferences().getValue(DEVICE_ID) as? String | ||
| if (deviceId.isNullOrBlank()) { | ||
| // Lazy init for upgrades: existing installs won't have a device_id yet | ||
| val anonId = anonymousId | ||
| if (anonId.isNotBlank()) { | ||
| getPreferences().setValue(DEVICE_ID, anonId) | ||
| return anonId | ||
| } | ||
| return "" | ||
| } |
Member
There was a problem hiding this comment.
we should use a lock here similar to anonymousLock
- Remove initDeviceId() and call getDeviceId() during setup instead, since they do the same thing - Add deviceIdLock to synchronize getDeviceId() for thread safety, matching the pattern used by anonymousLock
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
$device_idto the Android SDK for stable device-level feature flag bucketing across identity changesidentify()andreset()calls, and is sent in/flagsrequest payloadsProblem
Users running experiments targeting anonymous users see variant assignments flip when
identify()orreset()changes thedistinct_id. The hash changes, causing a different bucket and different variant for the same physical device.Changes
PostHogPreferences: AddDEVICE_IDconstant and include inALL_INTERNAL_KEYSPostHogFlagsRequest: Add optionaldeviceIdparameter, serialized as$device_idPostHogApi.flags(): ThreaddeviceIdparameter toPostHogFlagsRequestPostHogRemoteConfig: ReaddeviceIdfromcachePreferencesinexecuteFeatureFlags()and pass to APIPostHog.kt:initDeviceId()— seeds device_id from anonymous ID on first setupreset()— preservesDEVICE_IDacross resets (alongsideVERSIONandBUILD)getDeviceId()— public method with lazy-init fallback for SDK upgradesPostHogInterface: AddgetDeviceId()to public API surfaceTest plan
PostHogFlagsRequestTesttests (includes/excludes device_id)PostHogTesttests (init, persistence, identify/reset preservation, flags payload, lazy-init upgrades)