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 every bug report, feature request, and vote, 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
Link a real user to their anonymous session:
await mite.identify({
user_identifier: 'user_123',
email: 'user@example.com',
name: 'Taylor',
metadata: { plan: 'pro' },
})The SDK includes the current anonymous_id automatically so the backend can
link the anonymous user to the known one. Device info is attached automatically
too. Every field on IdentifyUserPayload is optional — calling
mite.identify({}) just re-syncs the current anonymous identity.
Once identified, the user_identifier is persisted and reused on subsequent bug
reports, feature requests, and votes until you call logout().
Reading the current identity
mite.anonymousId // string
mite.userIdentifier // string | undefined
mite.isIdentificationOptedOut // 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.anonymousId)SDK methods that need identity (submitBug, identify, createFeatureRequest,
voteFeatureRequest, getFeatureRequestVotes) already await this internally —
you only need it for direct getter reads.
Logging out
Clear the identified user while keeping the anonymous ID stable:
await mite.logout()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 anonymous_id — it
needs something to group activity by — but stops sending user_identifier,
email and name fields, metadata, reporter contact fields, and default
device_info.
await mite.setIdentificationOptOut(true)To re-enable identification:
await mite.setIdentificationOptOut(false)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_identifier. Turning identification back on
does not restore it — call 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 win over instance state for that single request.