Engineering

Why we rebuilt Found It's sync engine from scratch

VibeCode CreationsMay 28, 20266 min read
#engineering#firebase#android

When we launched Found It, sync was a thin wrapper around Firestore's offline persistence. That held up fine until organizations with hundreds of daily reports started hitting conflicts: two people resolving the same "found" item within seconds of each other, on spotty campus Wi‑Fi.

The problem with last-write-wins

Firestore's default merge behavior is last-write-wins per document. For a single user editing their own data, that's invisible. For a shared queue of lost-and-found reports, it meant a finder's "claimed" update could silently overwrite a moderator's "archived" update a few seconds later.

What we changed

We moved status transitions into a small state machine enforced both in the client and in Firestore security rules, so an invalid transition is rejected before it ever reaches another device:

const allowedTransitions: Record<ReportStatus, ReportStatus[]> = {
  open: ["matched", "archived"],
  matched: ["claimed", "open"],
  claimed: ["archived"],
  archived: [],
};

Each transition now carries a monotonically increasing revision field. Clients reject incoming updates with a revision lower than the one they already applied locally, which removed almost all of the conflict reports we were seeing in the field.

Results

Since shipping this in v2.3.0, conflict-related support tickets dropped by roughly 80%, and sync latency on slow connections improved because clients stopped re-fetching documents to "double check" state after every write.

We'll go deeper on the security-rules side of this in a follow-up post.