Build custom mobile interface using FieldPulse API

We're evaluating building a stripped-down mobile interface for our technicians using the FieldPulse API — basically a custom PWA that hits the standard REST endpoints and renders what we need without the full native app experience.

Before I sink too much time into prototyping, has anyone actually gone down this road? Specifically curious about:

  • Offline behavior — does the API expose conflict resolution, or are we rolling our own sync logic?
  • Photo upload reliability over spotty cell — any gotchas with the multipart/form-data endpoints?
  • Real-time updates — polling /work_orders every 30s feels wrong. Webhooks to a mobile PWA seems awkward too.

I've got a basic proof-of-concept working for read-only views, but I'm hitting some friction around session handling that makes me wonder if this is a path FieldPulse actually supports or just tolerates.

YMMV obviously, but would love to hear from anyone who's shipped something like this to actual techs in the field.

Parents
  • Hey Devon — yeah, this is a pattern we see more than you'd think. The API absolutely supports it, though you're right to flag the gaps.

    Offline / Conflict Resolution

    No server-side conflict resolution exposed. You get updated_at timestamps on every record, so last-write-wins is your baseline. Worth noting: the native app uses a different sync protocol (not public) that handles this more elegantly. For a PWA, I'd recommend:

    // Store pending mutations with local timestamp
    const pending = {
      id: crypto.randomUUID(),
      entity: 'work_order',
      entity_id: 'wo_123',
      payload: { status: 'completed' },
      attempted_at: Date.now(),
      retry_count: 0
    };

    Then replay in order, checking updated_at on the server response to detect collisions.

    Photo Uploads

    The multipart endpoint is solid, but connection drops mid-upload are painful. We don't support resumable uploads (no range headers), so you're re-uploading the whole file. Pro tip: compress client-side aggressively. The native app downsamples to 1600px on the longest edge before upload — copying that behavior saves headaches.

    Real-Time

    Polling is honestly fine for most field workflows if you're smart about it. Cache aggressively, poll only when the app is foregrounded, and use since parameters:

    GET /work_orders?updated_since=2025-07-26T10:00:00Z&limit=50

    Webhooks to mobile are architecturally awkward unless you're running a backend that pushes to Firebase/APNs. If you've got that infrastructure, great. If not, polling keeps it simple.

    Re: session handling — are you using OAuth or API keys? OAuth refresh tokens can be finicky in a PWA context depending on your IdP's iframe policies. API keys are simpler but obviously less secure on a shared device.

    Happy to dig deeper on any of this. There's a longer writeup in the API docs that covers mobile-specific patterns.

Reply
  • Hey Devon — yeah, this is a pattern we see more than you'd think. The API absolutely supports it, though you're right to flag the gaps.

    Offline / Conflict Resolution

    No server-side conflict resolution exposed. You get updated_at timestamps on every record, so last-write-wins is your baseline. Worth noting: the native app uses a different sync protocol (not public) that handles this more elegantly. For a PWA, I'd recommend:

    // Store pending mutations with local timestamp
    const pending = {
      id: crypto.randomUUID(),
      entity: 'work_order',
      entity_id: 'wo_123',
      payload: { status: 'completed' },
      attempted_at: Date.now(),
      retry_count: 0
    };

    Then replay in order, checking updated_at on the server response to detect collisions.

    Photo Uploads

    The multipart endpoint is solid, but connection drops mid-upload are painful. We don't support resumable uploads (no range headers), so you're re-uploading the whole file. Pro tip: compress client-side aggressively. The native app downsamples to 1600px on the longest edge before upload — copying that behavior saves headaches.

    Real-Time

    Polling is honestly fine for most field workflows if you're smart about it. Cache aggressively, poll only when the app is foregrounded, and use since parameters:

    GET /work_orders?updated_since=2025-07-26T10:00:00Z&limit=50

    Webhooks to mobile are architecturally awkward unless you're running a backend that pushes to Firebase/APNs. If you've got that infrastructure, great. If not, polling keeps it simple.

    Re: session handling — are you using OAuth or API keys? OAuth refresh tokens can be finicky in a PWA context depending on your IdP's iframe policies. API keys are simpler but obviously less secure on a shared device.

    Happy to dig deeper on any of this. There's a longer writeup in the API docs that covers mobile-specific patterns.

Children
  • Thanks Eli — super helpful framing. The collision detection approach is basically what I landed on, good to know I'm not missing some hidden server-side capability.

    On session handling: we're using OAuth with PKCE, and the refresh token dance in a service worker context is... not great. Safari in particular kills the SW after 7 days of no site interaction, which bricks the token refresh. We're looking at a hybrid model where the native app (if installed) handles auth and passes a short-lived API key to the PWA via deep link, but that's feeling pretty hacky.

    Curious if you've seen anyone solve this cleanly, or if we're just pushing against platform limitations here.

  • We've shipped a custom tech-facing PWA for ~60 users. Notes:

    • Conflict resolution: rolled our own with vector clocks. Overkill for most, but we needed merge semantics for checklist responses.
    • Photos: implemented chunked upload ourselves — split to 500KB chunks, POST to a lambda that reassembles and forwards to FieldPulse. Not elegant, eliminates the retry pain.
    • Auth: abandoned OAuth for this use case. API keys scoped per-technician, rotated weekly via automated job. Acceptable risk for our threat model.

    One gap worth flagging: work_order.notes doesn't surface read receipts, so concurrent editing is genuinely dangerous. We disabled inline editing and force append-only.

    Docs on API authentication are current as of last month. The mobile-specific section Eli mentioned is accurate.