Web · 2024
RentMate — Equipment Marketplace
Equipment-hire marketplace with three roles — renter, owner, admin — backed by Firestore. Availability is the hard problem: bookings overlap, owners cancel, and the renter list has to stay live without polling. Modelled it with Firestore listeners and per-asset availability docs.

The problem
A peer-to-peer equipment-hire marketplace. Three roles: renters browse and book, owners list and manage equipment, admins moderate. The genuinely hard problem is availability — when a renter is browsing, they should see what's actually free right now, not what was free at page load. Owners cancel. Bookings overlap. Two renters might try to book the same window simultaneously.
Approach
React frontend, Firebase for everything backend (Auth, Firestore, hosting). Auth was straightforward — Firebase's role-claim model fit the three roles cleanly. The interesting work was the data model.
Each asset has a separate availability subdocument that the renter view subscribes to via Firestore listeners. Bookings write to that subdocument with the requested window; conflicting writes fail at the rule layer (no double-booking the same hour) before they hit business logic. The renter list is genuinely live — no polling, no manual refresh — because Firestore pushes the new state on commit.
Key decisions
Per-asset availability docs over a single bookings collection
A central bookings collection would have been simpler to write but harder to subscribe to efficiently — every renter would be watching the whole collection. Per-asset docs keep the watcher footprint proportional to what's on screen.
Firestore security rules as the conflict guard
Pushing the "no overlapping bookings" check into Firestore rules eliminated the need to coordinate with a Cloud Function for the common case. Conflicts fail at write time, atomically.
Firebase as the entire backend
For a CRUD-heavy three-role app at this scale, going pure Firebase removed an entire backend service from the architecture. The trade-off is vendor lock-in, which I accepted in exchange for shipping speed and zero ops.
Outcome
Live on Firebase Hosting. All three roles work end-to-end. Availability is genuinely live across concurrent renters thanks to Firestore listeners, with no polling overhead.