Skip to main content

Overview

useAccounts returns the list of all stored accounts and the currently active account. Use it to render an account switcher or display the signed-in user’s identity.

Usage Example

Returns

StoredAccount[]
Array of all stored accounts, derived from the accounts map in Redux state. Each one carries the profile summary, the two credential markers below, and the needsPushRebind notification marker.
StoredAccount | null
The account currently selected, or null when nothing is selected.Selection and session are not the same thing, and the gap between them is a state your UI has to render. An account can be selected with no live session behind it — during an addAccount() flow, or after a sign-in was refused at the account limit. Read accessToken from useAuth for whether a session exists; read this for whose account the app is pointed at.
number
Total number of stored accounts.
boolean
true when there is no active account because the user deliberately signed out — or removed the active account, deleted it, or had a stored credential refused at launch — as opposed to “nothing has ever been selected”. Both look like activeAccount === null; this is what tells them apart, and it is persisted, so it survives a relaunch.A launch that could not reach the server does not set it: the stored account stays selected and its session is restored later. Only a refusal counts.While it is true, the SDK will not auto-select a stored account at launch. It clears as soon as any account is successfully activated.
boolean
true when an account was actually refused admission because the map was already at the 5-account limit. Clears on the next successful admission and on any removal. See useAddAccount for how it differs from canAddAccount and from wouldExceedAccountLimit.Render off it — do not read it eagerly. The clear is dispatched from an effect, so it lands one render after a successful admission rather than synchronously inside the call that caused it. Reading it immediately after awaiting a sign-in returns the value from before that effect flushed, which may be a true left over from an earlier, unrelated refusal. See When accountLimitReached clears.

StoredAccount Type

StoredAccount is a superset of the AccountSummary shape stored in the account map, so code that only reads id/name/username/email/avatar is unaffected.

Telling a Live Account From a Dead One

A stored account can stop working while it is sitting in the switcher. Two fields let you show that before the user taps it, and you need both — neither is sufficient on its own:
number
Proactive. Read from the stored refresh token’s own exp claim when the entry is written (a decode, never a verification and never a network call).0 means unknown — the token carried no readable numeric exp, so the SDK recorded nothing rather than guessing. It sorts as already-expired deliberately: treating a credential the SDK cannot read as fresh is the worse failure.
boolean
Reactive. Set when a transition into this account is refused — by a switch, or by the automatic restore at app launch, which is the most common way a revoked credential is discovered. Cleared the moment the account is successfully activated again, whether by a switch that works or by signing into it afresh.This catches every death tokenExpiresAt cannot see: reuse detection, a password change, a remote sign-out-all, an admin revocation. All of those destroy the token family while exp is still comfortably in the future. It is also set without any network call when the stored entry carries no usable credential at all, which is the same conclusion reached sooner.A failed switch that could not reach the server does not set it — a flaky network is not a dead account. AccountTransitionError.credentialRejected is the same distinction, reported to the caller at the moment of failure; see useSwitchAccount.

Notifications paused: needsPushRebind

boolean
true when this account’s push binding points at a device token this device no longer holds, because the token rotated while the account was in the background.Its credential is fine and its data is fine — only the notification routing is stale. Switching into the account re-creates the binding and clears this, so the useful thing to render is an invitation to open it rather than a sign-in prompt: “Notifications paused — open to resume.”Only ever raised for accounts that explicitly enabled push on this device. An account that never asked for notifications has none to pause.
Do not conflate it with needsReauth. They mean opposite things about the account’s health, and saying the wrong one is wrong in both directions: telling a user to sign in again when their notifications are merely stale asks for a password they do not need, and treating a paused account as fine hides the one thing a tap would fix. Neither credential marker is a promise: needsReauth: false with a future tokenExpiresAt means nothing has gone wrong that the SDK knows of, not that the next switch is guaranteed to succeed. A switch can still fail, and when it does the current session is left untouched — see When a transition fails. On Expo, avatar and then email may be dropped from a stored entry if it would otherwise exceed SecureStore’s per-value limit. id, name, username, the credential and the markers are never dropped. See Where accounts are stored.

Rendering the Signed-Out State

No account is auto-selected after a sign-out, removal or deletion, so activeAccount can be null while accounts is non-empty. That is the account-picker state:
Branch on accessToken, not on activeAccount. A selection is not a session: addAccount() leaves the previous account selected while it clears the session, so a selection-based gate would render your app for an account that has no tokens behind it. signedOut then separates the picker state from a device where nobody has ever signed in.

Integration Guide

For multi-account integration guidance, see Multi-Account.