Users and identity
Identify signed-in users in a hybrid app, wait for their assignments before reading flags, and return to the anonymous device identity on logout.
The SDK starts with an anonymous device ID. Call identify(userId) on login and identify(null) on logout. Await each call before you read flags for the new identity.
Device ID and user ID
On first launch the SDK creates a random device ID and stores it. Apex assigns tests to this ID until the app calls identify().
| Property | Value |
|---|---|
Apex.deviceId | The anonymous device ID. undefined before configure(). |
Apex.userId | The identity the SDK currently uses: the user ID after identify(), otherwise the device ID. |
Use a stable user ID from your own system. Do not use an email address or a phone number.
Log in
async function onLogin(user: { id: string }) {
await Apex.identify(user.id);
// Read flags here. They now return this user's values.
const enabled = Apex.flag('welcome', false);
}identify() never rejects. It resolves when the new user's assignments load, or after initTimeoutMs (default 3,000 ms).
User IDs are non-empty strings of up to 1,024 characters. The second argument, attributes, is accepted but not sent to Apex.
Why you await identify
Until the new user's assignments load, the SDK keeps serving the previous identity's values. During this time:
- Flag reads return the previous values and record no exposure.
logExposure()calls are ignored and are not replayed later.
After the new assignments load, read the flag again or call logExposure() again. The SDK then counts the exposure for the new user. If the wait times out, reads stay uncounted until a matching response arrives.
If the app calls identify() again before the first call finishes, the later call wins.
Identify at startup
If the app already knows the signed-in user at startup, identify before the first render. This prevents an exposure for the anonymous device of a user who is in fact signed in:
await Apex.configure(options);
if (session.userId) await Apex.identify(session.userId);The NGXS service accepts a userId option for this.
Log out
async function onLogout() {
await Apex.identify(null);
}identify(null) returns to the device ID and clears the saved user for the next launch.
Cold launch
The SDK saves the identified user per shop and environment. On the next cold launch, it restores that user's cached assignments at once, before it waits for the network. Without a saved user, it restores the anonymous device cache.
Purchases during a login change
While identify() is pending, trackPurchase() still works. The base purchase row uses the new identity. The per-test copies use the previous identity and its assignments. After the new assignments load, all rows use the new identity.