Architecture
who talks to whom.
One picture of the three parts you deploy (operator console, Firebase backend, mobile app) and the outside services they call. Read it once before you set anything up: most setup problems are a broken arrow in this picture.
01The diagram
Boxes with a solid border are the parts in this package. Boxes with a dashed border are outside services you open accounts for. Arrows point in the direction the request goes.
02What each arrow means
| From → to | What travels | If it breaks |
|---|---|---|
| Console → Firestore | On start and on every save the console writes config/public (what the app may see) and config/private (your keys, read only by Functions), with the Firebase Admin SDK and your service account (admin/src/firebase.ts, admin/src/sync.ts). It also reads users, alerts, stats and revenue for its pages. | Status shows "Firestore is reachable" or "App config written to Firestore" failing. See Service account and permissions. |
| Functions ↔ Firestore | The API reads the config (kept 60 seconds in memory, firebase/functions/src/api/context.ts) and writes cache, alerts, purchases, revenue events and statistics. | If the config documents are missing or unreadable, the API quietly uses the built-in defaults: everything that earns money is off. See Firestore connectivity. |
| App → Functions | Every screen's data: markets, coins, charts, news, brief, wallets, alerts, purchases, and the app configuration from GET /v1/config. The address is the API_BASE_URL the app was built with. | The app shows the setup screen (no address) or "Market data is temporarily unavailable". |
| App ↔ Firebase Authentication | A silent anonymous account for every user, plus the Google, Apple and e-mail buttons you leave on. The app sends the sign-in token to the API with each account request. | Account requests answer 401 unauthenticated ("Sign in first.") when the token comes from a different Firebase project than the API. |
| App ↔ Firestore | Only the user's own optional cloud backup, users/{uid}/sync/watchlist|portfolios|wallets, protected by firebase/firestore.rules. Nothing else in Firestore is readable by the app. | Backup does not sync; the rest of the app keeps working. |
| Functions → market data | CoinGecko (CoinMarketCap as failover), Alternative.me for Fear & Greed, the RSS feeds and public RPC nodes, with the keys from config/private. | Cached data with a "Cached" label, or "Market data is temporarily unavailable". |
| Functions → AI provider | The market brief and coin reports, only when AI is on and your key is set. | The labelled Automatic summary is shown instead. |
| Functions → store server APIs | Verification of every purchase with Google Play and the App Store before Pro, Remove ads or AI credits are granted (firebase/functions/src/iap.ts). | Purchases are refused with iap_unconfigured or "could not be verified". |
| Functions → FCM → app | Price-alert and campaign push messages (firebase/functions/src/push.ts). The console never sends push itself. | No push; see Alerts and push. |
| App ↔ ad SDKs and store billing | The ad SDKs load ads with the unit ids from /v1/config; the AdMob app id is also compiled into the native project. Purchases go through the phone's store. | See Ads do not show in release builds. |
No third-party key is ever inside the app: CoinGecko, CoinMarketCap, AI and store keys live in the console (encrypted) and in config/private, which only Cloud Functions read. The console's Test buttons also call those providers from the console server, never from your browser.
03Where each part runs
| Part | Runs on | Set up in |
|---|---|---|
| Cloud Functions, Firestore, Authentication, Cloud Messaging | Your Firebase project (Blaze plan) | Firebase backend |
| Operator console | Any Node 22 host you choose, behind HTTPS | Operator console |
| Mobile app | Your users' phones, published in Google Play and the App Store | Installation, Release |
New to all of this? Follow Step-by-step setup, which goes through the parts in the right order.