← Back to Finn
AgentFinn
Mobile offline synchronization
Synchronizes local edits through durable queues with explicit conflict handling and account isolation.
mobile-offline-sync
See how it helpsWhen is it useful?
Use when users must edit without a connection and synchronize later.
What does it help you do?
- Chooses the necessary offline scope and local storage model.
- Orders repeat-safe outgoing changes and incremental incoming updates.
- Handles conflicts, schema upgrades and account-switch cleanup safely.
Try asking this
Sync offline task edits after reconnection and keep one account's queued changes out of another account.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Offline Storage & Synchronization
Design local persistence and offline behavior around the actual product requirement—keeping offline read caches, crash-safe local drafts and deferred write outboxes strictly separated.
1. Choose the right level of offline support
| Tier | When to Use | Storage & UI Behavior |
|---|---|---|
| 1. Offline Read Cache | Feeds, profiles, reference catalogs, orders/tickets that must remain viewable in subways/airplanes. | Persist query cache or SQLite tables (stale-while-revalidate). Show cached data immediately with an unobtrusive offline/last-updated indicator; revalidate on reconnect. |
| 2. Crash-Safe Local Drafts | Multi-step forms, messages, inspection notes or media uploads that must survive app switching or network drops. | Auto-save drafts locally (keyed by userId + entity/screen key) on input debounce and on background/inactive transition. Clear draft only after server confirmation. |
| 3. Offline Mutation Outbox | Field-service, note-taking or task apps where product requirements explicitly mandate offline authoring. | Apply change to local DB with syncStatus: 'pending', enqueue mutation in a persistent FIFO outbox table, and replay when online. Never invent an outbox for flows like payments or live inventory booking that require immediate server validation. |
2. Outbox synchronization, idempotency and ordering
- Client-generated IDs & Idempotency-Key: generate a UUIDv4/UUIDv7 on the client (
clientMutationId/Idempotency-Keyheader) when the mutation is created. If the connection drops after the server commits the write but before the device receives the200 OK, replaying the outbox item with the same key must be safe and deduplicated. - Sequential dependency resolution: replay mutations per entity/aggregate in causal order (
CREATE->UPDATE->DELETE). If an item is created and edited while offline, either coalesce the pending mutations in the outbox or map temporary client IDs to server IDs before sending dependent requests. - Retry backoff vs permanent failure:
- Transient errors (
5xx, network timeout,429): retry with exponential backoff + jitter, triggered by connectivity restoration (NetInfo/connectivity_plus) or foreground resume. - Permanent rejections (
400,403,404,409,422): never loop forever. Mark the outbox entryfailed, preserve the user's payload, and surface a clear banner/action so the user can edit, retry or discard the change.
- Transient errors (
3. Delta pull sync and conflict resolution
- Pull incremental updates using server cursors, sync tokens or
updated_sincewatermarks inside a single local database transaction so readers never observe half-applied sync batches. - Conflict handling (
409 Conflict/ version mismatch):- Send the base
versionorupdatedAtwith offline edits. - Only use silent Last-Write-Wins (LWW) for trivial preferences. For user-authored records, preserve both the server state and the user's local changes so nothing is silently overwritten.
- Send the base
4. Database hygiene, migrations and multi-account safety
- Schema migrations: every change to
expo-sqlite, WatermelonDB, Drift, Room or CoreData/SwiftData schemas must bumpschemaVersionand provide a tested migration path (onUpgrade/MigrationStrategy) so existing users upgrading the app never crash or lose unsynced outbox items. - Encryption at rest: when storing sensitive health, financial or enterprise records offline, enable SQLCipher (
useSQLCipherinexpo-sqlite/sqflite_sqlcipher/ encrypted Room) with the encryption key stored in iOS Keychain / Android Keystore. - Storage eviction & sign-out wipe: bound cached media/attachment directories, refuse to sign out silently while unsynced outbox mutations exist without warning the user, and wipe all user-scoped tables, KV entries and cached files on logout.
Before you finish
- Offline read cache, local drafts and outbox mutations are separated and matched to product rules.
- Outbox writes attach stable
Idempotency-Keys, respect causal ordering, and halt on4xxerrors. - Conflict resolution preserves user work; delta pulls commit atomically in transactions.
- Local DB schema migrations are versioned, and sign-out warns on unsynced work and wipes user data.
Included files 2
LICENSE.txtSKILL.md
