For hyperlocal grocery delivery platforms, the most production-proven approach we've seen is a WebSocket layer for active deliveries combined with REST for everything else.
Here's the breakdown that works at scale:
Location Updates: Use WebSockets (Socket.io on Node.js works well) for delivery partner location pings every 3–5 seconds while an order is active. Outside active delivery windows, drop to a polling heartbeat to reduce server load.
Order State Management: Treat order status as an event stream. Each state change (confirmed → packed → picked up → out for delivery → delivered) fires a server-sent event that updates the customer app, store panel, and admin dashboard simultaneously.
Firebase as a Middle Layer: Reasonable for early-stage builds. Firebase Realtime Database handles the location sync well and removes WebSocket infrastructure management. The trade-off is cost at scale and some lock-in. If you're building for multi-city operations, abstract the location layer behind your own service from day one.
Offline Handling: Cache the last known location and last confirmed state locally on the delivery partner app. On reconnection, sync the delta. Never let a connectivity gap reset the order flow.
For reference, this is the same architecture pattern used in full-stack grocery delivery app development platforms built for multi-store, multi-city operations where the admin dashboard, store panel, and customer app all need consistent real-time state.
The most common mistake is building the customer tracking UI first and retrofitting the backend sync later. Design the event pipeline first, then build the UI around it.