Cryptocurrency Tracker docs
v2.0.0
Live demoConsole demo Get help
● Ship · Fixes

Troubleshooting
symptom, cause, fix.

The problems you are most likely to meet, grouped by part. Press / to search for an error message.

01App

SymptomCause and fix
Setup screen "Set your API address"The build has no API_BASE_URL. Run or build with --dart-define=API_BASE_URL=https://<region>-<project>.cloudfunctions.net/api, no trailing slash.
Setup screen "Connect your Firebase project"lib/firebase_options.dart is still the placeholder. Run flutterfire configure in app/ (Installation).
"Market data is temporarily unavailable"The API answered 503 upstream_unavailable: every provider failed and nothing was cached. Usually CoinGecko's keyless rate limit. Enter a free CoinGecko Demo key, and a CoinMarketCap key for failover (Data providers).
A "Cached" label on dataThe provider failed and the last cached value is shown ("stale": true). It clears on the next successful fetch.
The "All" chart shows only one yearCoinGecko's Public and Demo plans serve 365 days of history ("limitedTo":"1y"). A Pro plan serves the full history.
Charts or exchange tickers missing while prices workThey come only from CoinGecko. CoinMarketCap can replace prices, not history.
The 1H button is greyed out in candle mode ("Candles start at 24H")Intended, on every CoinGecko plan: CoinGecko's smallest candle is 30 minutes, so the shortest candle range is 24H. Switch the chart to Line for 1H (Candlesticks).
Candles for ALL show only one year ("ALL limited to 1Y by the data plan")The Public and Demo plans serve 365 days of candles; days=max is answered with the last year and "limitedTo":"1y". A CoinGecko Pro plan serves the full history.
Candles do not load but the line chart works, or neither loadsGET /v1/coins/{id}/ohlc answered 503 chart_unavailable: CoinGecko failed (often the keyless rate limit) and nothing was cached. Candles are a separate CoinGecko call per range; enter a CoinGecko Demo key.
The Fear & Greed card is missing on the markets screenEither Console → Features → Fear & Greed index on Markets is off (the API answers 404 not_found), or Alternative.me is down and nothing is cached: GET /v1/feargreed answers 503 upstream_unavailable and the app hides the card until the next refresh. Check <API_BASE_URL>/v1/feargreed in a browser (Fear & Greed index).
No "Community sentiment" card on a coin pageCoinGecko has no community votes for that coin ("sentiment": null), or the coin data came from the cache of an older backend version; it appears once the coin detail is fetched again (cache time "Coin detail", default 10 minutes).
Animations do not playThe phone asks apps to reduce motion (iOS Reduce Motion, Android Remove animations). The app then skips decorative animation on purpose (Motion).
"The account could not be deleted. Please try again."DELETE /v1/me failed: no network, more than 5 tries in a minute, or a server error (Functions → Logs). Nothing is lost by retrying; a repeated deletion is safe (Account deletion).
A Google, Apple or e-mail sign-in button shows "Sign-in failed"That provider is not enabled under Firebase → Authentication → Sign-in method, or (Apple) the capability or provider settings are missing (Sign-in methods). Enable the provider, or switch the button off in the console under Settings → Sign-in methods.
"This account has been suspended"The user is banned in the console (Users page). Unban there.
Wallet: "This address is not valid for the selected chain"Wrong chain or format (formats). Bitcoin xpubs are not supported.
Wallet shows fewer tokens than an explorerOnly tokens among CoinGecko's top 250 are shown; others are counted as hidden (Verified tokens).
Wallet lookups fail at busy timesThe free public RPC endpoint is rate-limited. Add your own RPC URL in Console → Wallet chains.
No adsAds are off by default: switch on Show ads and at least one placement, and enter the ids. Pro and Remove-ads users never see ads. Release builds never use test ids. New ad units can take time to fill. Step-by-step check: Ads do not show in release builds.
Purchase fails with "The store is not available on this device"If the API log shows 503 iap_unconfigured, store verification is not set up in the console (Purchases).
Purchase not granted after payingThe API answered 400 "The purchase could not be verified" (Functions log). Bundle id or package name in the console does not match the build; the product id differs; or the App Store environment is Production while you test in the sandbox.

02Alerts and push

SymptomCause and fix
No push on iPhoneNo APNs key in Firebase, missing Push Notifications capability, notifications denied, or a Simulator. Test on a real device (APNs key).
No push on Android 13+The user denied the notification permission. Enable it in the system settings.
Alerts never fireFirebase → Functions → Logs: look for evaluateAlerts every 5 minutes. If it is missing, the project is not on Blaze or Cloud Scheduler is not enabled; deploy again.
Alert fired late or missed a spikeAlerts are checked every 5 minutes against current prices; a spike between two checks is not seen.
"You have reached the limit of your plan" when adding an alertThe server enforces the active-alert limit (free 3, Pro 100 by default). Change it in Console → Pro and purchases.
A campaign stays "scheduled"sendCampaigns runs every 5 minutes; check its logs.

03News and AI

SymptomCause and fix
News tab emptyConsole → Status shows each feed's result. A feed that answers but is not RSS or Atom, or blocks the server, is skipped. Check that refreshNews runs (Functions → Logs).
Always "Automatic summary", never AI"Use AI" is off, no key is set, the daily cap is reached, or the provider failed. The Functions log says AI call failed; using the automatic summary with the reason, and Status tests the key (fallback).
AI on, but users see a paywall for reportsThat is the gating: Pro, free allowance, credits or a rewarded ad (AI summaries). Raise "Free AI coin reports per user and day" to give everyone some.

04Widgets

SymptomCause and fix
iOS widget shows its empty state ("Add coins to your watchlist in the app") although the app has dataThe App Group differs between the app, the extension and the code. Fix all four places (App Group) and register the group for both App IDs.
Widget says "Open the app to enable widgets"Console → Features → Home-screen widgets is off. Turn it on; the widgets show data again after the user opens the app (Widget switches).
Widget says "Widgets are a Pro feature"Console → Pro and purchases → Home-screen widgets for Pro only is on and the user has no Pro. Intended; turn the switch off to give everyone widgets.
Settings → Home-screen widgets says "The operator has switched home-screen widgets off" or "Home-screen widgets are a Pro feature"The same console switches as above, shown in the app. The Pro notice opens the Pro screen. In the web demo the row says widgets are available in the Android and iOS apps.
Widget prices update rarelyThe operating system schedules widget refreshes (target: every 30 minutes) and delays them under battery saving. Opening the app refreshes them at once.

05Backend and console

SymptomCause and fix
firebase deploy fails on functionsThe project is not on Blaze, or a Google Cloud API is not enabled yet; the CLI usually names it. Node.js must be 22.
npm run dev:api: EADDRINUSEPort 8787 is in use. PORT=8788 npm run dev:api and the same port in API_BASE_URL.
Console: "Firestore is reachable" failsGOOGLE_APPLICATION_CREDENTIALS points to a missing file or a key of another project; or set FIREBASE_PROJECT_ID. Exact messages and fixes: Service account and permissions.
Console: stored keys stopped working after a moveADMIN_SECRET_KEY changed. Use the original key, or enter the secrets again.
Lost the setup codeRestart the console: each start before the owner exists prints a new code.
Status lists "skipped" linesA settings list line is invalid (news source, waterfall, affiliate, sponsored slot). Fix the line as shown.
Changes in the console do not reach the appThe API caches /v1/config for 60 seconds and the app loads it when it starts; restart the app. Check "App config written to Firestore" on Status. If Status is green but the app still shows defaults, the console and the API may use different Firebase projects (Firestore connectivity).

06Service account and permissions

The console reaches Firestore with the Firebase Admin SDK and a service account (admin/src/firebase.ts). When that fails, the console still starts, but its log shows [admin] config sync failed: <message> and Status shows "Firestore is reachable" or "App config written to Firestore" failing with the same message. The first four messages below were reproduced with this console on 2026-10-13.

Message in the log or on StatusCause and fix
The file at /path/service-account.json does not exist, or it is not a file. ENOENT: no such file or directoryGOOGLE_APPLICATION_CREDENTIALS points to a file that is not there. Use the full path, without quotes, and check the file name. In Docker the path must exist inside the container (mount the file).
Unable to detect a Project Id in the current environment.No credentials and no project id were found: GOOGLE_APPLICATION_CREDENTIALS is empty and the host has no attached service account. Set GOOGLE_APPLICATION_CREDENTIALS (and check that .env sits in the admin/ folder you start from).
Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.FIREBASE_PROJECT_ID is set but there are no credentials. Set GOOGLE_APPLICATION_CREDENTIALS, or run on Cloud Run / Compute Engine with an attached service account.
16 UNAUTHENTICATED: Request had invalid authentication credentials. Expected OAuth 2 access token…The key file is not valid any more: the key was deleted or disabled in Google Cloud, or the file was edited. Create a new key (Firebase console → Project settings → Service accounts → Generate new private key) and point to it.
7 PERMISSION_DENIED: … (Google's wording varies; not reproduced here)The credentials work but the account may not use Firestore in this project: a service account from another project, or a custom account without a Firestore role. Give it the Cloud Datastore User role (roles/datastore.user) in Google Cloud → IAM for this project, or use the key Firebase generates (Project settings → Service accounts), which has access as created.
5 NOT_FOUND: … mentioning the database (not reproduced here)Firestore has not been created in this project yet, or the key is for a different project. Create the database (Build → Firestore Database) or use the right key. Check the project id inside the key file ("project_id").
"Something went wrong reading Firestore. Check the server log." on a console pageA product page (Users, Alerts, Revenue…) failed to read Firestore (admin/src/routes.ts). The real error is in the console's terminal log. A message about a missing index means the indexes were not deployed: run firebase deploy --only firestore:indexes from firebase/.

Which roles

WhoNeeds
The console's service accountRead and write access to Firestore only: Cloud Datastore User (admin/README.md). The console uses no other Google service; it never sends push itself. The key Firebase generates for its Admin SDK service account already has access.
Console on Cloud Run or Compute Engine without a key fileAttach a service account with Cloud Datastore User to the service and leave GOOGLE_APPLICATION_CREDENTIALS empty (Deploy options).
You, when you run firebase deployA Google account with Owner or Editor rights on the project, so it can deploy functions, rules and indexes and enable the APIs the deploy asks for.
Google Play purchase verificationA separate service account, pasted into Console → Pro and purchases, or the Cloud Functions service account invited in Play Console with "View financial data" (firebase/README.md). See Purchases.
The key is powerful

A service-account key bypasses Firestore security rules. Keep it only on the console's server, never in the app, in git or in a support message. If a key leaks, delete it in Google Cloud → IAM → Service accounts → Keys and create a new one.

07Firestore connectivity

SymptomCause and fix
Console log says config/public + config/private v… written and Status is green, but the app still shows the default name, colour and no adsDifferent projects. The console wrote to one project and your API runs in another. Compare the "project_id" in the key file (or FIREBASE_PROJECT_ID) with the project in your API_BASE_URL and in firebase/.firebaserc. The API does not report this: when it cannot find config/public it quietly uses the built-in defaults, where everything that earns money is off (firebase/functions/src/api/context.ts). Checked on the emulator: a console started with another project id wrote its config there, and the expected project had no config/public.
The console log says data: Firestore emulator 127.0.0.1:8080 on your serverFIRESTORE_EMULATOR_HOST is set, so the console talks to a local emulator instead of your real database. Remove the line from the production .env (an empty value is fine) and restart.
Local testing: the console, the API and the app do not see each other's data on the emulatorsEveryone must use the same emulator project id. The emulators accept any id, so a mismatch shows no error, only empty data. The package uses demo-cryptotracker everywhere (npm run serve, the console's default with FIRESTORE_EMULATOR_HOST, the placeholder firebase_options.dart). If you set FIREBASE_PROJECT_ID or ran flutterfire configure, use that id on all three (emulators).
App on the Android emulator cannot reach the local emulatorsUse --dart-define=USE_EMULATOR=true; the app then uses 10.0.2.2, the Android emulator's address for your computer. On a real phone pass your computer's network address with EMULATOR_HOST=<ip>. Never ship a build with USE_EMULATOR=true.
Account features answer 401 unauthenticated ("Sign in first.")The app signs in with the Firebase project in lib/firebase_options.dart, and the API only accepts tokens from its own project (firebase/functions/src/api/auth.ts). Run flutterfire configure with the same project the API is deployed to, and check that the Anonymous provider is enabled.
Cloud backup of the watchlist, portfolios or wallets does not syncThe app writes only users/{uid}/sync/… directly to Firestore, and only the deployed rules allow it. Deploy them: firebase deploy --only firestore:rules. A failure is not shown to the user; in a debug run the log has a line starting with sync push or sync pull (app/lib/services/sync_service.dart). The user must also be signed in with Google, Apple or e-mail ("Sign in to back up your data").
Console pages are empty although the app has usersThe console reads the project in its key file. Check the project id as in the first row. On a sample-data console (ADMIN_DATA=sample) nothing is read from Firestore at all; remove that line on your real install.

08Ads do not show in release builds

Debug builds use Google's test ads when an AdMob unit id is empty. Release builds never do (app/lib/ads/native_adapters.dart), so a release build exposes every missing id. Work through this list in order.

  1. Status in the consoleConsole → Status → "Ad ids set for what is switched on". "Ads are on but every placement is off: nothing is shown." means no placement is on. "Release builds show no ad without these ids — …" lists exactly which ids are missing for the networks in your waterfall.
  2. The settings really reached the appAds are configured from /v1/config each time the app starts. Close the app completely and reopen it (the API keeps the config up to 60 seconds). Open <API_BASE_URL>/v1/config in a browser and look at the ads part: enabled must be true and your unit ids must be there. If they are not, see Different projects. The app does not keep ad settings offline: if it starts without a connection, it shows no ads in that session.
  3. The AdMob app id in the native filesAdMob reads its app id from the app bundle, not from the console. The package ships Google's test app id ca-app-pub-3940256099942544~3347511713 in app/android/app/src/main/AndroidManifest.xml (com.google.android.gms.ads.APPLICATION_ID) and Google's test id in app/ios/Runner/Info.plist (GADApplicationIdentifier). Replace both with your own and build again (Enter your ids). The app id in the native files and in Console → AdMob ids must be the same AdMob app.
  4. Pro and Remove adsUsers with Pro or the Remove-ads purchase never see ads (app/lib/ads/ad_policy.dart). Test with an account that has neither; check the Users page in the console.
  5. ConsentIn the EEA and UK the app first shows Google's consent form (UMP). Without a published message in AdMob → Privacy & messaging, ads may not be served there (Consent).
  6. New ad units and new appsNetworks often serve few or no ads to brand-new ad units and to apps that are not yet live or not yet reviewed by the network ("no fill"). This is on the network's side: wait, check the network's dashboard for the app's review status, and link the app to its store listing once it is published. In a waterfall the next network gets its turn when one does not fill.
  7. Interstitial spacingInterstitials respect "Seconds between two interstitials" (default 120) and "Interstitial on every n-th coin opened"; app-open ads show at most once an hour. Fewer ads than expected is often just these limits.
Never click your own live ads

To test a release build, add your phone as a test device in each network's dashboard instead.

09Build

SymptomCause and fix
iOS build errors in Google Mobile Ads headers after upgrading packagesgoogle_mobile_ads is pinned to 9.0.0 on purpose: 9.1.0 fails to compile with use_frameworks! (comment in app/pubspec.yaml). Keep the pin until it is fixed upstream.
CocoaPods errorscd app/ios && pod repo update && pod install. CocoaPods 1.16 or newer.
Widget extension missing from the Xcode projectcd app/ios && ruby scripts/add_widget_extension.rb (idempotent).
Gradle or JDK errorsUse JDK 17 or newer and Android SDK 36; run flutter doctor.