Why we rebuilt Found It's sync engine from scratch
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.