Skip to content
ZENITH_LABS
All Insights
WEB ARCHITECTURE9 min read

The Architecture of an Offline-First PWA: IndexedDB, Firebase Sync, and Edge Deployment

How to build a web application that works seamlessly without an internet connection — including the conflict resolution strategy that keeps data consistent when connectivity is restored.

By IEEE-published AI researcher & founder of Zenith Labs

TL;DR

  • Offline-first means the local database (IndexedDB) is the primary data source — the network is treated as an optional sync layer, not a requirement for function.
  • Conflict resolution is the hard problem: when two clients mutate the same record while offline, the merge strategy must be explicit and deterministic. Last-write-wins is rarely correct for structured data.
  • Combining Firebase RTDB for real-time sync with a Cloudflare Edge deployment gives you sub-second response times globally while keeping your offline logic entirely client-side.

01Why 'Offline-First' Is Different From 'Works Offline'

Most applications are online-first: they query the server, display the result, and fall back to a cached version if the network fails. Offline-first inverts this: the application reads from and writes to a local database as the primary action, and syncs with the server as a background process whenever connectivity is available.

The Khedma platform — a service management application for multi-role community organisations — required true offline-first architecture because its users operate in environments with intermittent connectivity: field workers checking in attendance, coordinators updating schedules, and parents submitting requests, all potentially on slow or absent mobile data. A loading spinner that never resolves is a failed product for this use case.

02The Local Data Layer: IndexedDB With a Mutations Queue

All reads in Khedma go directly to IndexedDB — the browser's built-in structured database. Writes also go to IndexedDB first, and simultaneously append a mutation record to a persistent mutations queue stored in a separate IndexedDB object store.

Each mutation record contains: a UUID, a timestamp, the operation type (create / update / delete), the target collection and document ID, the full payload, and the user's role and session context. This queue is the single source of truth for what the local client has done that the server does not yet know about.

When connectivity is detected (via the Navigator onLine API and a background service worker ping), the sync engine processes the mutations queue in order, applying each operation to Firebase RTDB and removing successfully synced records from the queue. The UI reflects the local state immediately — there is no waiting for server confirmation before the user can continue working.

03Conflict Resolution: The Part Nobody Talks About

Conflict resolution is the part of offline-first architecture that most tutorials skip. The scenario: User A updates a record at 14:00 while offline. User B updates the same record at 14:05 while offline. Both users come online at 14:10. Whose changes win?

Last-write-wins (decided by timestamp) is the simplest policy and is wrong for most structured data. If User A updated a student's attendance status and User B updated the same student's contact number, both changes should survive — they touched different fields.

Khedma implements field-level merge: each mutation stores a diff object containing only the changed fields. Conflicts are resolved by merging diffs at the field level, with a per-field timestamp to resolve cases where the same field was updated by two clients. Only when two clients update the exact same field of the exact same record within the same sync window does a true conflict exist — and in that case, the system surfaces a visible conflict flag to the relevant administrator rather than silently discarding data.

04Firebase RTDB, RBAC, and Edge Deployment

Firebase Realtime Database provides the sync backbone: its WebSocket connection enables sub-100ms propagation of changes across all connected clients once they are online. Security Rules enforce role-based access control at the database level — servants can only read and write their own service records, parents can only access their children's data, and admins have full collection access.

The Next.js application is deployed on Cloudflare Edge with API routes running as Edge Functions. This means the application shell, authentication logic, and API endpoints are served from data centres geographically close to every user — critical for users in regions where latency to a single origin server would degrade the perceived performance of the sync engine.

PWAIndexedDBFirebase RTDBOffline-FirstCloudflare EdgeNext.jsRBAC

Apply This to Your Business

Ready to put this into practice?

Every engagement starts with a structured discovery session. No commitment required.

Start a project