Sync and connectivity¶
How the mobile app talks to the server — background sync cycles, real-time updates, and how to trigger a sync manually.
Required role
Any mobile-enabled role.
Overview¶
The mobile app stays in step with the server using three mechanisms:
- Background sync — a scheduled cycle that runs every 15 minutes, whether the app is open or not.
- Real-time WebSocket — a persistent connection that pushes live updates while the app is in the foreground.
- Manual sync — pull-to-refresh or the Force sync button, for when you want to pull changes immediately.
If the device is offline, everything queues. Work you do offline saves locally; on reconnect, the outbox uploads and server-side changes download. See Working offline.
Background sync¶
The app runs a sync cycle every ~15 minutes:
- Android: cadence is usually tight to the 15-minute mark unless the device is in low-power / battery-saver mode.
- iOS: the operating system aggressively throttles background work — cadence can stretch to 15–60 minutes based on battery level, whether the device is on charge, how often you use the app, and whether Low Power Mode is on.
If you need an update immediately rather than waiting for the next cycle, use Settings → Force sync or pull-to-refresh on the Dashboard.
What a sync cycle does¶
Each cycle performs:
- Upload pending items from the outbox:
- Submitted task forms.
- Photos queued for upload.
- Mapper changes (created hierarchy nodes, written NFC registrations).
- Repair requests and shutdown reports.
- Download server-side changes:
- New task assignments.
- Updated hierarchy (delta sync — only what's changed since the last cycle).
- Updated master data.
- Translation updates.
- Profile / role changes.
- Refresh caches where needed.
Background sync is delta-based, not full-download. On a mature installation, a sync cycle is fast — it only transfers what's changed.
Battery impact¶
Minimal. Each cycle takes a few seconds on good connectivity and does no work if there's nothing to upload or download. The OS further throttles the cycle when the device is on low battery.
Real-time WebSocket¶
When the app is in the foreground, it holds a persistent WebSocket connection to the server. This delivers instant updates for:
- New task assignments pushed to you by a Supervisor.
- Task approval / rejection by a Supervisor.
- Repair request status changes on requests you raised.
- Shutdown updates relevant to your assets.
The real-time connection is encrypted and pinned to the server's TLS certificate, so it's safe against ordinary network interception.
Connection indicator¶
On the Dashboard, a small icon shows the WebSocket state:
- Green — connected, live updates flowing.
- Orange — reconnecting.
- Red — disconnected; updates will catch up on next background cycle.
When the WebSocket doesn't run¶
- When the app is backgrounded or killed (iOS and Android both suspend the socket).
- When the device is offline.
- When a corporate firewall blocks WebSocket upgrades.
In all these cases, background sync still delivers updates — just a little later.
What the fallback looks like¶
When the connection indicator is orange or red, the live WebSocket is down but the app is not broken:
- New assignments still arrive — on the next background cycle (every ~15 minutes on Android, up to 60 min on iOS).
- Submissions still upload — via the outbox on the next cycle, or immediately if you pull-to-refresh.
- Approvals and rejections still reach you — on the next cycle, with a slight delay.
The practical effect of a disconnected WebSocket is: you see updates 1–15 minutes late instead of instantly. Nothing is lost, just delayed. If your site has chronic WebSocket blocking (corporate firewall), the app is still fully usable — you'll just rely on pull-to-refresh for "right now" views.
Manual sync¶
Three ways to force an immediate sync:
Pull-to-refresh on the Dashboard¶
Drag down from the top of the Dashboard. A spinner appears. Within a few seconds, the app pushes the outbox and pulls down server changes.
Settings → Force sync¶
Settings → Force sync runs the same cycle as pull-to-refresh, with a more detailed progress view. Useful when you want to see exactly what's uploading and downloading.
On app open¶
Every time you open the app, a light sync runs automatically to catch up on anything that happened while the app was backgrounded.
Sync on specific events¶
The app also triggers small, targeted syncs on specific events:
- After submitting a task — tries to upload immediately if connected.
- After taking a photo — photo upload starts right away if connected.
- After tapping a notification — syncs the specific entity the notification references.
The Pending uploads badge¶
The Dashboard shows a badge: Pending uploads: N. It counts:
- Submitted tasks waiting to upload.
- Photos waiting to upload.
- Mapper changes waiting to upload.
When N > 0, you have work queued locally. When it reaches 0, everything's been accepted by the server.
End of shift check
Before you put the device down, verify Pending uploads = 0. If it's not, move to a location with good signal and give it a minute. If it still won't clear, see Sync is stuck or failing.
Photo upload specifics¶
Photos upload separately from form data — typically after the form submission succeeds. Why:
- Photos are much larger than form data.
- A flaky network can complete a small form upload and fail the photos.
- Uploading them separately means a form submission isn't blocked by photo failures.
The app tries each photo a few times before marking it failed; failed photos stay in the outbox and retry on the next cycle.
Token refresh¶
The access token the app uses to authenticate with the server expires and refreshes automatically in the background. You won't notice this unless:
- Your password changes on the server side — you'll be signed out and need to sign in again.
- Your account is deactivated — same.
Handling server-side schema changes¶
When the server deploys a new version that changes the data model (new fields on a form, new task type), the app pulls those changes on the next sync cycle. Form rendering is dynamic — the app doesn't need an update to show new fields.
If a schema change introduces a field the app genuinely can't render (rare), you'll see a prompt to update the app.
Things to watch for¶
Old device clock
The server trusts timestamps from the device. If the device clock is wrong, your submission times look wrong on the server. Keep automatic time sync on at the OS level.
Aggressive battery savers
Some Android manufacturers (particularly Samsung, Xiaomi, Huawei) ship with aggressive battery savers that kill background jobs from any app. If background sync isn't running reliably on one of these devices, exempt the app in the phone's battery settings.
Wi-Fi vs mobile data
The app doesn't care which network you're on. If you're on unmetered Wi-Fi, syncs are slightly faster because photos upload in parallel. On metered mobile data, the app can be configured to defer large photo uploads until Wi-Fi returns (Settings → Data usage).
Troubleshooting¶
| Problem | See |
|---|---|
| Pending uploads won't clear | Sync is stuck or failing |
| New assignments aren't appearing | Pull-to-refresh, then check Tasks aren't showing |
| Photos stuck uploading | Photo upload is failing |
| WebSocket indicator stays red | Firewall may block; background sync will still run |
| Background sync never runs on this device | Check battery saver / doze settings |
Related topics¶
- Working offline — the offline-first design.
- Executing a task — where sync most often matters.
- Settings — where the Force sync button lives.