DEV Community

Nando Rama
Nando Rama

Posted on

Building “Squares” with ChatGPT: From Prompts to a Commercial-Ready App (Day 7)

About this journey

I’m a former embedded coder who left Lockheed in the mid-1990s and haven’t seriously coded since. Beyond reading about today’s platforms, I came into this project knowing nothing about React, Next.js, Firebase, Vercel, or modern web app infrastructure. My goal is to have ChatGPT handle 99% of the coding while I guide the design, test the app, and provide feedback. What you’re reading is a day-by-day journal of building “Squares” — a commercial-ready sports squares app — with AI as my development partner.


Day 7: Email-Link Auth that Actually Works + Safer Preview Testing on Vercel

Theme: untangling Firebase Email-Link auth on Vercel, aligning domains and env vars, and adding a guarded “dev login” for Preview so I can iterate without hitting quotas.

What broke (and why)

  • auth/unauthorized-continue-uri: Magic links failed because my runtime app was pointed at the wrong Firebase project (env mismatch), even though the allowlisted domain looked right.
  • Local .env* confusion: Repo had .env.local, .env.staging, .env.production. Vercel uses its own Environment Variables; those files were misleading the build.
  • Quota exceeded: Rapid testing hit auth/quota-exceeded, which pushed me to add a Preview-only bypass.

The fixes that stuck

1) Make the continue URL deterministic

  • Build continueUrl from NEXT_PUBLIC_AUTH_RETURN_BASE (Preview uses https://squares-staging.vercel.app), falling back to window.location.origin.
  • Log runtime Firebase config (apiKey/projectId/authDomain) and the final continueUrl for instant visibility.

2) Use Vercel envs as the source of truth

  • Verified Preview variables:
    • NEXT_PUBLIC_FIREBASE_API_KEY
    • NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN
    • NEXT_PUBLIC_FIREBASE_PROJECT_ID
    • NEXT_PUBLIC_AUTH_RETURN_BASE=https://squares-staging.vercel.app
  • Moved local .env* files out of the app tree to avoid accidental use during builds.

3) Map the domain to the right environment

  • Vercel → Project → Settings → Domains Connected squares-staging.vercel.app to Preview (branch staging). Result: magic links that land on /auth resolve in the same environment that sent them.

4) “Remember this device” and route after sign-in

  • Set Firebase persistence to browserLocalPersistence so signed-in users skip auth on revisit.
  • Email-link completion reads ?role=manager|player and routes accordingly.
  • If already signed in and not on a link-complete URL, route to the last chosen role.

5) Preview-only dev login (no email needed)

  • Client flag: NEXT_PUBLIC_BYPASS_MAGIC_LINK=true (Preview only).
  • Server route: /api/dev-login issues a short-lived custom token via Firebase Admin only if:
    • A secret header matches DEV_LOGIN_SECRET, and
    • The request is from the Preview deployment.
  • Production path is unchanged; the bypass is Preview-scoped and guarded.

Small but meaningful UX tweaks

  • Manager dashboard
    • Added a Logout button next to Create New Square.
    • Free tier status now: “Free tier • 1 square at a time until {Mon DD} • Active squares: N”
    • Purchase panel starts collapsed; Free Tier activation appears inside the dialog (less “prototype,” more “product”).

What I learned (again)

  • If the error says “domain not allowlisted,” verify the runtime Firebase project. Logging apiKey/projectId/authDomain beats guessing.
  • Vercel Preview vs Production is mostly domains + env vars. Map correctly, set envs correctly, and the rest gets pleasantly boring.
  • Quotas are real. A guarded Preview bypass keeps velocity high without compromising production auth.

Reflections from Day 7

This was a classic “it’s configured… just not the way you think” day. Once I surfaced the runtime values and mapped the domain to Preview, Firebase Email-Link auth behaved. The guarded dev login let me iterate without poking the quota hornet’s nest. Bonus: a couple of small UI touches made the Manager dashboard feel like a product, not a demo.

✅ Next steps

  • Vibe-code the “Create New Square” flow
    • Minimal form: matchup/title, grid size (5×5 / 10×10), start/end, visibility.
    • Client validation + friendly errors.
    • Firestore write (draft → active), with optimistic UI on create.
    • Invite flow stub (paste emails now; deeper contact picker later).
    • Preview-only safeguards (no billing), Prod path ready to integrate with purchasing.

Top comments (0)