Installation
from the zip to your phone.
The full path: your Firebase backend, the operator console, then the app on an Android or iOS device, built against your own API.
01What is in the package
The download has three folders: source/ (the code: app/, firebase/, admin/, docs/CONTRACT.md, README.md, CHANGELOG.md), documentation/ (these pages) and licenses/. Every path and command in this documentation starts in source/.
| Folder | What it is |
|---|---|
app/ | The Flutter app: Android, iOS and a web demo mode. Screens in app/lib/ui/, ads in app/lib/ads/, purchases in app/lib/iap/, texts in app/lib/l10n/app_*.arb (9 languages), Android widgets in app/android/app/src/main/kotlin/, the iOS widget extension in app/ios/CryptoTrackerWidget/. |
firebase/ | Cloud Functions (TypeScript, Node 22): the /v1 API and four scheduled jobs, Firestore security rules and indexes. |
admin/ | The operator console, a small Node server built on the MIKODES Admin Kit. |
docs/CONTRACT.md | The data and API contract shared by the three parts: every endpoint, Firestore collection and setting with its default. |
02The order
- Firebase backendCreate the project, upgrade to Blaze, enable Anonymous sign-in and Firestore, deploy. You get your
API_BASE_URL. Firebase backend - Operator consoleRun it with a service account, create the owner, set the legal URLs and a CoinGecko key. Operator console
- Your idsChoose your app name, Android application id and iOS bundle id before you connect the app to Firebase. Rebranding
- The appBelow.
03Connect the app to Firebase
The app ships with a placeholder app/lib/firebase_options.dart with empty values. While it is in place, a normal build shows a setup screen instead of the markets. Replace it with your project's values:
dart pub global activate flutterfire_cli
cd app
flutterfire configure --project=<your-project-id> # choose android and ios
FlutterFire registers the Android and iOS apps in your Firebase project with the application id and bundle id it finds in the project, and rewrites lib/firebase_options.dart. That is why you change the ids first. These files hold your project's public client identifiers; keep them in your own private repository.
The app signs every user in anonymously in the background; nothing else is needed for the app to work. Users can also sign in to sync their lists across devices (app/lib/services/auth_service.dart). The sign-in screen shows Google, e-mail and Apple (iOS and web); each one can be switched off in the console under Settings → Sign-in methods, and with all three off the screen says that sign-in is not offered. Keep a method on only after enabling the same provider under Firebase → Authentication → Sign-in method (Google, Apple, Email/Password), or a button the user taps will fail with "Sign-in failed". App Store guideline 4.8: if Google is on, keep Apple on for iOS. Apple sign-in also needs the Sign in with Apple capability on your App ID (the entitlement is already in app/ios/Runner/Runner.entitlements) and the Apple provider settings in Firebase.
04Run the app on a device
cd app
flutter pub get
flutter run --dart-define=API_BASE_URL=https://us-central1-<your-project-id>.cloudfunctions.net/api
Use your region and your own domain if you set up the Hosting rewrite (API_BASE_URL). No trailing slash.
Build switch (--dart-define) | Meaning |
|---|---|
API_BASE_URL=<url> Required | Your backend. Empty = the setup screen (except in demo mode, where it defaults to /api). |
DEMO_MODE=true | Web demo: no Firebase, data in the browser, simulated ads and purchases. Not for store builds. |
USE_EMULATOR=true | Use the local Firebase Auth and Firestore emulators. |
EMULATOR_HOST=<ip> | With USE_EMULATOR: your computer's address. Default 10.0.2.2 on the Android emulator, localhost elsewhere. |
Source: app/lib/core/env.dart.
05iOS specifics
- Pods
cd app/ios && pod install(Flutter also runs it on the first iOS build). - SigningOpen
app/ios/Runner.xcworkspacein Xcode. Select your team under Signing & Capabilities for both targets: Runner and CryptoTrackerWidget (the home-screen widget extension). - App Group and pushBoth targets use the App Group
group.com.yourcompany.cryptotracker, and Runner has Push Notifications. Change the group with your bundle id (Rebranding) and register it in your Apple Developer account. - APNsUpload your APNs key to Firebase for push (APNs key).
06Optional: everything locally on the emulators
To test sign-in, alerts and the console against local Firebase emulators, with no cloud project (needs Java 21+):
cd firebase/functions && npm ci && npm run serve # auth 9099, firestore 8080, functions 5001
cd admin && npm ci
FIRESTORE_EMULATOR_HOST=127.0.0.1:8080 ADMIN_SECRET_KEY=$(openssl rand -hex 32) npm start
cd app
flutter run --dart-define=USE_EMULATOR=true --dart-define=API_BASE_URL=http://10.0.2.2:5001/demo-cryptotracker/us-central1/api # Android emulator
Do this before flutterfire configure, or with a configured app whose project id you also pass to the emulators: the placeholder firebase_options.dart uses the project id demo-cryptotracker, the same as the emulators. On iOS Simulator or desktop use 127.0.0.1 instead of 10.0.2.2. The scheduled jobs (alerts, news, brief, campaigns) do not run in the emulator, and push does not reach emulators.
07Run the tests
cd app && flutter analyze && flutter test
cd firebase/functions && npm test && npm run test:emu && npm run test:rules
cd admin && npm test && npm run test:emulator
Run each line from the package folder. test:emu, test:rules and test:emulator start the emulators themselves, so they need the Firebase CLI and Java. The app tests include a layout sweep of every screen in every language, in dark mode, at 360 px width.
08Before you publish
- Backend deployed;
<API_BASE_URL>/v1/healthanswers"ok":true - Console running over HTTPS, owner created,
ADMIN_SECRET_KEYanddata/backed up - Legal: privacy and terms URLs set; Status shows no blockers
- A CoinGecko Demo key (or better) entered and tested
- Your application id, bundle id, App Group, name and icon (Rebranding)
flutterfire configurerun with your ids- Your AdMob app ids in the native files if you use AdMob (Ads)
- Android upload key and iOS signing set up (Release)