Troubleshooting

Symptom-first fixes for the FoodFight client, mobile builds, and local dev. For step-by-step release guides, see Mobile and the linked Frontend pages.

Quick index

Symptom Jump to
npm install / npm start fails Client build
lucra-plugin / local package errors Client build
Native app shows old web UI Capacitor
Android signing / AAB fails Android
iOS archive / TestFlight issues iOS
Stuck on loading or wrong login state Auth
API 401 / wrong environment API & env
Deep link / referral / venue not applied Deep links
Stripe / Apple Pay / Google Pay fails Payments
Push not received Push
Customer.io empty / not connected Customer.io
Live fight updates missing WebSockets
Backend won’t start locally Backend (local)
Docs site won’t run Docs site

Client build (npm)

Symptom: npm install or npm start fails in client/.

Checks:

  1. Use a current Node LTS (team standard; re-install deps after switching versions).
  2. From repo root:
    cd client
    rm -rf node_modules
    npm install
    npm start
    
  3. If the error mentions lucra-plugin, build the local plugin first (Start here):
    cd ../lucra-plugin
    npm install
    npm run build
    cd ../client
    npm install
    npm start
    

Symptom: Tests fail with module mocks.

  • Client unit tests: cd client && npm test
  • See Testing

Capacitor (web + native out of sync)

Symptom: Code changes don’t appear in the iOS/Android app.

Fix: Rebuild web assets and sync native projects:

cd client
npm run build
npx cap sync

Then rebuild/run from Xcode or Android Studio.

Symptom: npx cap open ios / android opens a broken project.

  • Run npx cap sync after dependency or plugin changes.
  • Re-open the IDE project under client/ios or client/android.

More context: Start here — Capacitor.


Android

Symptom What to do
Keystore / signing error upload-keystore.jks is gitignored — get the file and passwords from the team. Expected alias: upload. See Android release.
Version code already used Bump versionCode in client/android/app/build.gradle, rebuild AAB.
Changes not in release AAB npm run buildnpx cap sync android → rebuild bundle.
Push doesn’t work on Android google-services.json must exist under client/android/app/. Without it, Gradle skips the Google Services plugin and FCM won’t work. See Push notifications.
Play upload rejected Read Play Console error (target SDK, permissions, signing). Full flow: Android release.

Command-line AAB (optional):

cd client/android
./gradlew bundleRelease

Output: client/android/app/build/outputs/bundle/release/.


iOS

Symptom What to do
Archive / signing / provisioning Use the team’s certs and match profiles; CI path: iOS release (Fastlane).
Web changes missing Same as Capacitor.
Apple Pay unavailable Native build only; set REACT_APP_APPLE_MERCHANT_ID. See Payments.
Lucra “bar games” missing Lucra is iOS-native and gated by feature flags — see client/src/utils/lucraUtils.js.

We do not rely on a working android_deployment GitHub workflow for store releases; Android is manual per the mobile doc.


Auth and session

Symptom: Blank loading screen forever.

  • AuthContext waits for checkedStorage after reading localStorage key tokens.
  • Clear site data / app storage and sign in again if tokens are corrupt.

Symptom: Logged in as wrong user / stale session.

// Browser devtools → Application → Local Storage (or clear app data on device)
localStorage.removeItem('tokens');

Reload the app.

Symptom: Partner dashboard redirects to sign-in.

  • Partner routes use PartnerRoute — user must have partner access in Cognito/backend.
  • See Routing & auth.

API and environment

Symptom: Calls go to prod while developing (or vice versa).

API hosts are chosen in client/src/utils/env.js and request modules (global/request/*):

  • Production: api.getfoodfight.link, auth.getfoodfight.link
  • Dev: api.ff-devs.click, auth.ff-devs.click

Notes:

  • Android native is treated as production for env selection.
  • Web uses REACT_APP_ENV and hostname (getfoodfight.link → prod).

Set REACT_APP_ENV and Stripe keys in client/.env for local web dev.

Symptom: 401 on API calls.

  • Token expired — sign out/in; AuthContext refreshes via refresh token when possible.
  • Wrong Bearer token on a manual fetch — prefer global/request/request.js helpers.

See API calls.


Symptom: server_code / venue / referral not applied after install.

  1. Confirm link shape — Deep links.
  2. server_code is set in Branch.io, not invented in the app.
  3. On native, enable debug:
    localStorage.setItem('dlDbgEnabled', '1');
    

    Console: [DLDBG]; trail: localStorage['dlDbgTrail'].

  4. Cold start vs warm: both BranchDeepLinkHandler and DeepLinkHandler must run (mounted in App.js).
  5. Web fallback: /open route (Open.js).

Symptom: Short Branch links don’t resolve.

  • DeepLinkHandler fetches *.app.link URLs; some in-app browsers block redirects — test on device with debug enabled.

Payments (Stripe)

Symptom What to do
Stripe Elements won’t load Check REACT_APP_STRIPE_TEST_KEY / REACT_APP_STRIPE_LIVE_KEY in .env; key selection in utils/env.js.
Apple Pay not offered Native iOS only; REACT_APP_APPLE_MERCHANT_ID set; Stripe.isApplePayAvailable() true.
Google Pay not offered Native Android only; Stripe.isGooglePayAvailable() true.
Payment succeeds but fight/reservation fails Backend must receive payment_intent.id after confirm — see fight PaymentStep / reservation checkout logs.

Full flow: Payments.


Push notifications

Symptom What to do
No permission prompt Push requires a native build; not supported in browser-only npm start.
Token never reaches backend After grant, PushNotifications hook calls addDevicePUT user/add_device. Check network tab / logs.
Android: no FCM Missing google-services.json — see Push notifications.

Customer.io

Symptom What to do
Customer.io analytics not available Init failed — check console from customerio-init.js; REACT_APP_CUSTOMERIO_API_KEY set.
Dashboard shows “not connected” on localhost Expected — CIO often needs a public URL; test on staging/prod.
Events missing User must be identify’d (sign-in/sign-up); check identify before custom trackEvent.
In-app messages never show Gist is disabled in code today (loadGist() returns false).
Server-side events Bet resolution and webhooks use backend libs/customerio — not covered by the frontend doc alone.

See Customer.io.


WebSockets (live fights)

Symptom: Profile fight status doesn’t update in real time.

  • WebSocket is built in components/websocket/WebSocketClient.js and used from Profile.js.
  • Requires valid userId + auth token; URL is built from env (wss in prod).
  • http site with wss URL can warn in console — test on matching scheme or native app.

See WebSockets. Historical design: App WebSockets (contributing).


Backend (local)

Symptom: Service won’t start or tests fail.

cd backend
make help

Common services: make user-service, make restaurant-service, make partner-dashboard-service, make down.

Symptom: Customer.io-related component tests need mock CIO.

  • Docker Compose profile customerio / wiremock_customerio — see backend/compose.yaml and Makefile targets that include --profile customerio.

Component / BDD tests: Local Tests.


Docs site

Symptom: make run fails in docs/.

cd docs
bundle install   # first time
make run

Site config: docs/_config.yml (Just the Docs). Published: foodfightv2.pages.dev.

Symptom: <link> placeholder broken after adding a page.

  • The docs do not support Jekyll/Just-the-Docs-style <link ...> placeholders or Liquid tags in our current tooling.
  • Use normal relative links like [Start here](./start-here.md) or a placeholder like <link> if you’re writing a stub.

Still stuck?

  1. Note platform (web / iOS / Android) and environment (local / dev / prod).
  2. Capture console + network errors (Sentry may already have them — Sentry).
  3. Check the feature map for which module owns the flow: Frontend overview.