Skip to main content
Roshan Aryal
All projects

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.

Visit liveSource private
RentMate — Equipment Marketplace preview
ReactFirebaseFirestoreTailwind

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.