Skip to content
Gates

Refresh and status.refreshing

When syncs happen

  • Startup. After the local read, in the background. Rendering does not wait.
  • Foreground. The Expo client listens to AppState; when the app becomes active it syncs if at least refreshIntervalMs (default 60 s) has passed since the last attempt. Otherwise it flushes telemetry instead.
  • Identity. 500 ms after identify or reset.
  • Manual. await gates.refresh().

One request runs at a time. A second caller joins the one in flight.

refresh()

const changed = await gates.refresh(); // true when the snapshot changed

Resolves true when a new snapshot replaced the current one, false otherwise (unchanged, offline, bad response). It never throws; a failure is reported in status().lastError.

status.refreshing

refreshing is true only while a refresh() your app called is in flight. Syncs the SDK starts itself at startup, on foreground and after an identity change never set it, so the value can go straight into RefreshControl:

const gates = useGates();
const { refreshing } = useGatesStatus();
<ScrollView
  refreshControl={<RefreshControl refreshing={refreshing} onRefresh={gates.refresh} />}
/>;

What a sync sends and gets back

POST /v1/sync with the key, environment, the revision the device holds, the installation id, the runtime info and, when known, the user. The API answers { changed: false } when the revision is current, or the full snapshot: { revision, changed: true, flags, audiences }. No deltas, no sockets.

A response is only applied if it passes the SDK’s shape guard. Anything else sets lastError and keeps the previous snapshot. See Offline and last-known-good.