Case studies
Local discovery / hospitality · 2024

Map-first discovery for time-sensitive local offers

Map-first discovery for time-sensitive local offers

Client
5-Live
Duration
12 week
Status
shipped & not available at this moment
Stack
Flutter · Google Maps SDK + Places API · FastAPI + Postgres · Redis

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

Login screen with Google and Apple one-tap sign-in Map view with filter chips and nearby results list Happening Now feed showing venues with live happy hours and drink specials Freemium paywall with 10-day trial and yearly plan

Reference architecture

The stack, one-pass.

Named pieces, how they connect, and why each one earned its spot.

  • 01Flutter

    one codebase for iOS and Android, fast iteration on filter UX

  • 02Google Maps SDK + Places API

    nearest-venue pins, distance sorting, reverse-geocoded search

  • 03FastAPI + Postgres

    typed endpoints for venue + happy-hour schema, geo queries via PostGIS

  • 04Redis

    cache "happening now" feed per geo-tile, refreshed per minute

  • 05Firebase Auth

    one-tap Google and Apple sign-in, no password flows to maintain

  • 06Store billing (RevenueCat)

    one SDK spans App Store and Play Billing, handles trial + refund edge cases

Full stack

Every piece, named.

  • Flutter
  • Google Maps SDK + Places API
  • FastAPI + Postgres
  • Redis
  • Firebase Auth
  • Store billing (RevenueCat)
The team on the call

Named engineers, not a pool.

You speak to the person who’ll review the architecture. No account-manager layer. No offshore switcheroo.

Founder & Lead Engineer

Sameer Donga

Shipping Flutter, FastAPI, and AI systems since 2019. Reviews the architecture on every engagement.

Start a similar build

You have the reference. Now the project.

Tell us the shape of your version. We come back with a written architecture and a fixed quote.