What we solved
Finding a bar with a live happy-hour drink special in the next 20 minutes is a dumb-sounding problem that every generic maps app still gets wrong. Google Maps knows the bar exists; it does not know the Mimosa is half-price until 3pm and only on Wednesdays. Yelp knows the menu; it does not sort by distance-plus-time-sensitive-offer.
5-Live needed a discovery surface that combined three things in one tap: nearest, right now, matches my drink. The rest of this page is how we built that surface and the pieces that make it feel instant on a cold start at a sidewalk.
The system at a glance
A native-feeling Flutter app on top of a FastAPI backend with a Google Maps data layer and a Redis-cached “happening now” index. Freemium subscriptions gate full data (100% of venues + no ads); the free tier gets the tease. Authentication is one-tap via Google or Apple - no email verification, no forgotten-password flows.
What the user experiences
- Open the app. Location is resolved once at startup (cached GPS + Places reverse-geocode).
- The map view loads venues within a walking-distance radius, pinned with the drink-category icon the user cares about: Brunch, Wine, Beers, Margs, Whiskey, Reverse Happy Hour.
- Day-of-week pills (Mon–Fri) let someone plan Thursday at lunch.
- The Happening Now feed sorts by what is live right this minute: AJUUA Mexican Grill, 10:00 AM – 3:00 PM,
$5 House Margaritas, Micheladas, Bloody Mary's, Sangrias, $2.50 Mimosas. Real prices. Real windows. No “call ahead to confirm.” - Save favourites, tap-to-call, tap-to-navigate, share the venue out.
How we built the pieces
Location services - Google Maps done properly
We use the Google Maps SDK for pins and map interaction, Google Places API for venue search and reverse geocoding, and a custom geo-tile cache on the backend so we are not re-hitting Places on every pan. The “nearest” sort runs server-side against PostGIS ST_Distance_Sphere, not client-side against raw lat/lon - the sort holds up at city scale, not just neighbourhood scale.
When the user is offline or flaky (walking between cell towers in downtown Austin), we serve the last-known tile from local storage and stamp it as stale in the UI, so the user is never staring at a blank map.
Backend - FastAPI + Postgres + Redis
Venue, operator, happy-hour window, and drink-category are a normalised schema in Postgres. Happy-hour windows are stored as tstzrange so a single query answers “which venues have an active window at wall-clock time now in local timezone?” without 50 lines of date-math in the app.
Redis sits in front as the “happening now” cache, keyed by geo-tile + 1-minute bucket. The first request to a tile in a minute costs Postgres; the next few hundred cost Redis. This is the thing that makes the feed feel instant at 4:59 PM on a Friday when everyone opens the app.
Auth - Firebase, one tap, no passwords
Firebase Auth ships Google and Apple one-tap sign-in, handles Apple’s private-relay email, and token-refreshes without us writing it. We skipped email-password entirely. Friday-evening bar app with forgotten-password flow is how you lose 40% of your funnel.
Subscriptions - one SDK, two stores
Freemium with a trial: first-time users get 10 days of full access, then a yearly plan. Store billing is wrapped by a single SDK so the App Store and Play Billing quirks (receipt validation, introductory-price rules, grace periods) stop being our problem. The paywall screen reads 30% Off List Price, 12 months for $20.99, $0.05/day - clear economics, no dark patterns.
Time-awareness is the whole idea
The reason most “bar finder” projects die at MVP is they ship the list view and never build the time-aware index. Venue hours change. Operators run weeknight specials. Brunch ends at 3. Without a live happy-hour index and a cheap read path, the list becomes stale within a week and users bounce. We built the index first, the UI second.
Results
- 4 screens built: auth, map discovery, Happening Now feed, subscription paywall.
- Data model handles multi-city rollout without schema changes (venue → city → timezone).
- Paywall shipping with trial + annual SKU; first-use economics are transparent.
What an engineering team should take from this
If you are building any flavour of “local discovery with a time dimension” - happy hours, live music, pop-up markets, yoga classes, clinic availability - the hard part is the time-aware index, not the map. Build the index, cache it per geo-tile, put a Google Maps skin on top. That is the pattern we ship.
Tech stack
- Mobile: Flutter (single codebase, iOS + Android)
- Maps & location: Google Maps SDK, Google Places API, PostGIS geo queries
- Backend: FastAPI, Pydantic, Postgres (PostGIS), Redis
- Auth: Firebase Auth (Google + Apple one-tap)
- Subscriptions: RevenueCat wrapper over App Store + Play Billing
- Infra: CI-driven deploys, staged releases, reversible migrations
Screens
