# AppFirebase

Flutter app with Firebase backend — generated by kasy.

---

## Documentation

Full Kasy documentation (CLI, iOS release, features, push, etc.) will be published at **[docs.kasy.dev](https://docs.kasy.dev)** (site coming soon).

In this project, use the local guides (links stay inside this repo only):

| Guide | Content |
|-------|---------|
| [docs/auth-setup.md](docs/auth-setup.md) | Enable Google, Apple and Facebook login |
| [docs/ios-release.md](docs/ios-release.md) | Publish to iOS on Mac (`kasy ios`) |
| [docs/codemagic-release.md](docs/codemagic-release.md) | Publish without a Mac (`kasy codemagic`) |

---

## Getting started

```sh
flutter run          # auto-detects device
make run-ios         # iOS
make run-android     # Android
```

**Physical device via cable**
- iOS: connect iPhone → trust this computer → Xcode → Window → Devices → pair
- Android: Settings → Developer options → enable USB debugging

**Backend deploy** (when ready):

```sh
kasy deploy
```

---

## Keys and credentials

This project uses two types of credentials. Understanding the difference avoids confusion when configuring.

### App keys (stay in the project)

They live in `.vscode/launch.json` as build environment variables (`--dart-define`). Flutter reads them via `String.fromEnvironment()`. **Never go to the server.**

| Variable | Module | How to get |
|----------|--------|------------|
| `RC_ANDROID_API_KEY` | RevenueCat | RevenueCat dashboard → Apps → Android → **Google Play** public key (`goog_…`) |
| `RC_IOS_API_KEY` | RevenueCat | RevenueCat dashboard → Apps → iOS → **Apple App Store** public key (`appl_…`) |
| `RC_WEB_API_KEY` | RevenueCat Web | RevenueCat dashboard → Apps → Web Billing → **production** key (`rcb_…`, not `rcb_sb_`) for release builds |

### RevenueCat: `test_` vs store keys (TestFlight / release)

- Keys starting with **`test_`** are RevenueCat **Test Store**: fine for **`flutter run` debug** on your Mac (fake purchases in RC’s test environment). **Do not** bake them into TestFlight/App Store IPAs — the SDK rejects them or the kit skips RC init.
- **TestFlight / Apple sandbox** (no real charges): use **store** public keys — **`appl_…`** (iOS) and **`goog_…`** (Android). TestFlight purchases still use **Apple/Google sandbox**, not real billing.
- The VS Code **Firebase — prod** config **no longer** sets RC keys; put `appl_` / `goog_` in **`Firebase/.env`** or **`.dart_defines`** (see `Makefile`) when building release / TestFlight.
- **Firebase — dev** still ships sample `test_` keys for local development only.
| `SENTRY_DSN` | Sentry | Dashboard Sentry → Project → DSN |
| `MIXPANEL_TOKEN` | Mixpanel | Dashboard Mixpanel → Settings → Token |

To update, edit `.vscode/launch.json` or pass via command line:

```sh
flutter run --dart-define=RC_ANDROID_API_KEY=your_key
```

---

### Server secrets (stay in GCP Secret Manager)

Used by **Cloud Functions** at runtime. **Never in the app code.**

| Secret | Used by | How to get |
|--------|---------|------------|
| `REVENUECAT_WEBHOOK_KEY` | Subscription webhook | Dashboard RevenueCat → Webhooks → Authorization header |
| `META_ACCESS_TOKEN` | Meta Conversions API | Meta Business Manager → System Users → Token |
| `META_DATASET_ID` | Meta Conversions API | Meta Business Manager → Events Manager → Dataset ID |

To configure or update each secret:

```sh
firebase functions:secrets:set REVENUECAT_WEBHOOK_KEY --project=YOUR_PROJECT_ID
firebase functions:secrets:set META_ACCESS_TOKEN --project=YOUR_PROJECT_ID
firebase functions:secrets:set META_DATASET_ID --project=YOUR_PROJECT_ID
```

> Each command asks for the value interactively. The value **does not appear** in the terminal.

To see existing secrets:

```sh
gcloud secrets list --project=YOUR_PROJECT_ID
```

---

## Internationalization (i18n)

The app supports **3 languages**: English (`en`), Portuguese (`pt`), and Spanish (`es`).

### How the language is chosen

```
App opens
  ├─ Has language saved by user? → use saved
  └─ No → read device/browser language
            ├─ Is en, pt or es? → use that language
            └─ None of these → use default language (base_locale)
```

### Change default language (fallback)

When the user's device is in an unsupported language (e.g. Japanese, French), the app uses the **default language**. Default is English. To change to Portuguese:

**`slang.yaml`**
```yaml
base_locale: pt   # change here: en | pt | es
```

Then run:
```sh
dart run slang
```

### Add or edit translations

Files are in `lib/i18n/`:
- `en.i18n.json` — English
- `pt.i18n.json` — Portuguese
- `es.i18n.json` — Spanish

After editing any `.i18n.json`, always run `dart run slang` to regenerate `translations.g.dart`.

### Language selector

The user can change the language in **Settings → Language**. The choice is saved on the device and restored on next app open.

---

## RevenueCat webhook

The webhook receives purchase events (new subscription, renewal, cancellation) from RevenueCat.

**In RevenueCat dashboard:** Webhooks → add function URL → Authorization header = value of `REVENUECAT_WEBHOOK_KEY`.

---

## Deploy

```sh
# Full deploy (Functions + Firestore rules + Storage rules)
firebase deploy --only functions,firestore:rules,storage --project=YOUR_PROJECT_ID

# Functions only
firebase deploy --only functions --project=YOUR_PROJECT_ID
```

---

## Publish to iOS (App Store)

Full guide: [docs/ios-release.md](docs/ios-release.md)

```bash
kasy ios configure   # once — Apple credentials
kasy ios release     # build IPA and upload to App Store Connect
```

No Mac: [docs/codemagic-release.md](docs/codemagic-release.md)

---

## Security

`.gitignore` already excludes: `firebase_key.json`, `.env`, `.env.*`, `*.pem`, `*.keystore`, `.kasy/apple.env`, `.kasy/codemagic.env`.

Never commit credentials to the repository.
