Identity Management
How user identification and anonymous tracking work in the Mite SDK.
Every Mite instance has an anonymous ID, generated on construction. It is attached to all feedback, errors, feature requests, and votes, so you can group a single user's activity without them ever logging in.
When mite.init() runs, the SDK syncs that anonymous ID to the identify
endpoint in the background. Failures there are swallowed — later calls reuse the
latest local state.
Persisting the anonymous ID
Pass identityStorage so the anonymous ID survives app restarts. Without it the
ID is in-memory only and a new one is generated on every full reload, which
makes one user look like many.
import AsyncStorage from '@react-native-async-storage/async-storage'
const mite = new Mite({
apiKey: process.env.EXPO_PUBLIC_MITE_API_KEY,
identityStorage: AsyncStorage,
})MMKV instances work directly — the SDK detects the getString/set/delete
shape and wraps it:
import { MMKV } from 'react-native-mmkv'
const mite = new Mite({
apiKey: process.env.EXPO_PUBLIC_MITE_API_KEY,
identityStorage: new MMKV(),
})Identity state is persisted under the @mite/sdk-identity key.
Identifying users
Call mite.user.identify() after sign-in to link a real user to their
anonymous session:
await mite.user.identify('user_123', {
email: 'user@example.com',
name: 'Taylor',
isPaying: true,
traits: { plan: 'pro' },
})The first argument is your own user ID. Every option is optional:
interface IdentifyOptions {
email?: string
name?: string
/** Mite alerts you when a paying user's report shows churn risk. */
isPaying?: boolean
/** Any other traits to keep on the user's profile. */
traits?: Record<string, unknown>
}The SDK sends the current anonymous ID with the call, so the backend can link the anonymous user to the known one. It attaches device info too.
Once identified, the user ID is persisted and reused on later feedback, errors,
feature requests, and votes until you call mite.user.reset().
Reading the current identity
mite.user.anonymousId // string
mite.user.id // string | undefined
mite.user.isOptedOut // booleanHydrating identity from storage is asynchronous. On app startup, await
whenIdentityReady() before reading these getters, or you may observe a
freshly generated ID rather than the persisted one:
await mite.whenIdentityReady()
console.log(mite.user.anonymousId)SDK methods that need identity (feedback.send, user.identify, and the
features methods) already await it. You only need it to read the properties
yourself.
Logging out
Call mite.user.reset() on sign-out. It clears the identified user and keeps
the anonymous ID:
await mite.user.reset()The anonymous ID is deliberately preserved so post-logout activity still groups with the same device.
Privacy opt-out
Switch the SDK into anonymous-only mode. Mite still sends the anonymous ID,
because it needs something to group activity by. It stops sending the user ID,
email and name, traits, reporter contact fields, and default device info.
await mite.user.optOut()To turn identification back on:
await mite.user.optIn()The preference is persisted alongside the anonymous ID, so it survives restarts. You can also start opted out:
const mite = new Mite({
apiKey: process.env.EXPO_PUBLIC_MITE_API_KEY,
identificationOptOut: true,
})Opting out clears the stored user ID. Opting back in does not restore it. Call
mite.user.identify() again.
Precedence rules
When identity state exists in more than one place, the SDK resolves it in this order:
anonymousIdin config wins over any persisted value.identificationOptOutin config wins over any persisted value. Leave it undefined to let the user's stored preference apply.- A persisted
userIdentifieris restored on startup unless opted out. - Per-call
anonymous_id/user_identifieroverrides on the deprecated 1.0 methods win over instance state for that single request.
Moving from 1.0
The 1.0 identity methods still work. They are deprecated and are removed in 2.0.
| 1.0 | Now |
|---|---|
identify({ user_identifier, email, name, metadata }) | user.identify(id, { email, name, traits }) |
logout() | user.reset() |
setIdentificationOptOut(true) / (false) | user.optOut() / user.optIn() |
anonymousId | user.anonymousId |
userIdentifier | user.id |
isIdentificationOptedOut | user.isOptedOut |