Overview
Fyre is “Beli for fashion”: an iOS, Android and web app where you swipe through full-screen outfits and rate each one with the swipe itself. Ratings feed a personalised For You page, alongside comments, DMs, sharing and profiles. It’s built with Expo and React Native on Firebase (Firestore, Storage, Cloud Functions), with typed Zod schemas shared between the app and the backend.
I’m one of three developers. Below is the work I designed and shipped.
What I built
- Swipe-to-rate. Replaced the original 0–100 slider with a single full-screen gesture: how far you swipe sets the tier, and releasing moves you to the next post. The pager runs on the UI thread, only the active page and its neighbours are mounted, the post heats from grey through gold to red as you pull, and haptics build in each tier. Tier thresholds and the rating variant come from Remote Config, so they can be tuned without a release.
- Three-tier ratings, end to end. Moved ratings to Lukewarm / Mild / Fyre across the data model, security rules, Cloud Functions and app. Per-tier counters update in one transaction, the recommender ranks by a Bayesian fyre rate, and the rules test suite grew from 15 to 58 cases.
- CLIP analysis service. A private, CPU-only FastAPI service on Cloud Run running FashionCLIP: one pass per post returns a 512-dimension image embedding plus scores for item and style labels supplied by the caller. Weights are baked into the image so cold starts never download a model, and prompt embeddings are cached (a warm call takes 0.04 s versus 1.58 s cold). It replaced a paid vision-LLM approach.
- Similar-fit retrieval for For You. Each user’s taste vector is built from the embeddings of posts they rated, weighted by tier and discounted for herd effects (ratings given while a high fyre count was visible count less). Firestore vector search finds look-alike posts, ranked by similarity, fyre rate and recency, with k-means and trending as fallbacks, so the feed never breaks if the index or embeddings are missing.
- Swipe telemetry pipeline. Every rating gesture is validated against a schema, buffered and written in batches (on 20 events, after 30 s, or when the app is backgrounded), with retries, a capped buffer and session tracking. It never throws to the UI. A follow-up analysis script turns it into tuning data for the swipe thresholds.
- Sharing and creation. Share to Messages, Instagram Stories and TikTok; a media-first, step-by-step post flow (pick, crop and filter, details); and style tagging after posting.
- CI and developer experience. A GitHub Actions pipeline running app, Cloud Functions and security-rule checks in parallel against the Firebase emulators, plus emulator auto-discovery from the Metro dev server so simulators and phones on the same network just work.
Engineering decisions
- No LLM in the ranking path. An LLM call per request is too slow and too expensive at social-app volume, and doesn’t learn taste. The plan is staged: content-similarity retrieval now, then a learned ranking model once there’s enough rating data, with CLIP for image understanding.
- Designed to degrade. Vector search sits behind an interface, so missing embeddings or a building index fall back to k-means and trending instead of an empty feed.
- Security rules as the contract. One rating per user, no self-rating, participant-only message threads and append-only telemetry, each covered by allowed-and-denied tests.
Status
In active development toward a beta.