MiteSDK

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 // boolean

Hydrating 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:

  • anonymousId in config wins over any persisted value.
  • identificationOptOut in config wins over any persisted value. Leave it undefined to let the user's stored preference apply.
  • A persisted userIdentifier is restored on startup unless opted out.
  • Per-call anonymous_id / user_identifier overrides 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.0Now
identify({ user_identifier, email, name, metadata })user.identify(id, { email, name, traits })
logout()user.reset()
setIdentificationOptOut(true) / (false)user.optOut() / user.optIn()
anonymousIduser.anonymousId
userIdentifieruser.id
isIdentificationOptedOutuser.isOptedOut

On this page