We built a field service app for a solar installer with 240 technicians across fourteen states. The single hardest requirement was not scheduling or routing. It was this: the app has to work perfectly with no signal at all, for an entire working day.
Offline is not a feature you add later
Retrofitting offline support into an app built around network calls means rewriting the data layer. Decide at the start, because the architecture is fundamentally different: the local database becomes the source of truth for the UI, and the network becomes a background synchroniser.
The queue is the design
Every user action writes to local storage immediately and appends an operation to an outbox. The UI reads only from local state, so it is instant and never shows a spinner. A background worker drains the outbox whenever connectivity returns.
Conflicts will happen — decide the rule up front
Two technicians edit the same job while both offline. Last-write-wins is simple and silently destroys data. We use per-field timestamps for independent fields, and for genuinely conflicting edits we keep both versions and surface them to a supervisor. The right answer is domain-specific; the wrong answer is not deciding.
Test on the phones your users actually own
The technicians in this deployment carried entry-level Android devices with 3GB of RAM, not the flagship on your desk. We keep a shelf of low-end handsets and test on them every sprint. It changes what you are willing to ship.
Photos are the hard part
Proof-of-work photos are large and there are many of them. We compress on device, queue uploads separately from data sync at lower priority, and never block job completion on an upload finishing. A technician should be able to close a job and drive away.