Overview
One physical device can hold several signed-in accounts, and each of them is bound to the device separately.useAccountPushToggle is the switch for that binding — per account, per device — and it works on accounts the user is not currently signed into.
The stored flag is durable intent: it lives in the account map next to that account’s credential, in the same platform storage, and it is merged into the entry rather than overwriting it — so it survives switches, relaunches, and the refresh-token rotation that rebuilds the entry on every launch and every transition. An account silenced here is still silenced after the app is force-quit and reopened, and stays silenced until something explicitly turns it back on. The server-side binding is disposable state that the SDK reconciles back to match the flag.
The flag has three states, not two. true and false are choices the user made; absent means the account has never been asked. Absent reads as enabled when describing an account — which is what isAccountPushEnabled below returns, and what a switch should render — but it is never treated as consent to create a binding. Nothing is bound for an account that has not explicitly opted in.
Requires the
push bundle. Reconciling is a no-op until this device has a stored push identifier — there is nothing to bind or unbind. usePushRegistration is what records one, through register(), unregister(), its rotation subscription, or — on native, when the device already holds notification permission — its mount-time read.Usage Example
Returns
({ userId, enabled }) => Promise<void>
Applies the binding change server-side first, then writes the flag and persists it.
userId may be any account in the stored map, active or not. Silencing a background account unbinds it server-side without switching to it, and without touching the current session.Rejects when the binding change fails.(userId: string) => boolean
Whether a stored account currently wants push on this device — the value to render as a switch’s
checked. An account that has never expressed a preference reads as enabled: absent means “never asked”, not “off”. Returns false for an unknown id.It is reported state, not the rule that decides whether a binding exists. An account reading as enabled purely because it never answered has no binding until it explicitly opts in — through this toggle, or through a register() that records a preference for every account that never had one.boolean
true while a change is in flight.string | null
The reason the last change failed, or
null.Failure Semantics
The flag is written only after the binding change succeeds. If the call fails, the previous value stands and the promise rejects. This is deliberate and it is not a UI preference: the SDK must never report an account as push-enabled while nothing is actually bound, or as silenced while a binding survives. What you render on failure — a reverted switch, a retry affordance, an inline error — is entirely yours. Failing here destroys nothing. The account stays, its credential stays, and the user can retry. An account whose binding is stale because this device’s push token rotated while it was in the background is a different situation, reported separately asneedsPushRebind on useAccounts and repaired by switching into the account — not by toggling it.
Turning Off a Background Account
Silencing an account the user is not signed into requires acting as that account for one request. The SDK does this by exchanging that account’s stored refresh token for a short-lived access token. That exchange rotates — it revokes the token it presents and issues a successor — so the SDK persists the successor before treating the operation as complete. You do not need to do anything about this, but it is why the operation involves a network round trip per background account rather than being instant, and why it is confined to this one deliberate, user-initiated path.Not the Same as Notification Preferences
They compose: an account silenced with this hook receives nothing on this device regardless of its event-type preferences, and those preferences are untouched — they apply again the moment it is turned back on.

