# AppFirebase

App Flutter con backend Firebase — generado por kasy.

---

## Documentación

La documentación completa de Kasy (CLI, release iOS, features, push, etc.) se publicará en **[docs.kasy.dev](https://docs.kasy.dev)** (sitio en preparación).

En este proyecto, usa las guías locales (solo enlaces dentro del repositorio):

| Guía | Contenido |
|------|-----------|
| [docs/auth-setup.md](docs/auth-setup.md) | Activar login con Google, Apple y Facebook |
| [docs/ios-release.md](docs/ios-release.md) | Publicar en iOS con Mac (`kasy ios`) |
| [docs/codemagic-release.md](docs/codemagic-release.md) | Publicar sin Mac (`kasy codemagic`) |

---

## Cómo empezar

```sh
flutter run          # detecta el dispositivo automáticamente
make run-ios         # iOS
make run-android     # Android
```

**Dispositivo físico por cable**
- iOS: conecta el iPhone → confía en este ordenador → Xcode → Window → Devices → emparejar
- Android: Configuración → Opciones de desarrollador → activar depuración USB

**Deploy del backend** (cuando estés listo):

```sh
kasy deploy
```

---

## Claves y credenciales

Este proyecto usa dos tipos de credenciales. Entender la diferencia evita confusión al configurar.

### Claves del app (quedan en el proyecto)

Están en `.vscode/launch.json` como variables de entorno de build (`--dart-define`). Flutter las lee vía `String.fromEnvironment()`. **Nunca van al servidor.**

| Variable | Módulo | Cómo obtener |
|----------|--------|--------------|
| `RC_ANDROID_API_KEY` | RevenueCat | Panel RevenueCat → Apps → Android → clave pública **Google Play** (`goog_…`) |
| `RC_IOS_API_KEY` | RevenueCat | Panel RevenueCat → Apps → iOS → clave pública **Apple App Store** (`appl_…`) |
| `RC_WEB_API_KEY` | RevenueCat Web | Panel RevenueCat → Apps → Web Billing → clave **producción** (`rcb_…`, no `rcb_sb_`) en builds release |

### RevenueCat: `test_` vs tienda (TestFlight / release)

- Clave **`test_`** = **Test Store** de RevenueCat: sirve para **`flutter run` en debug** en tu Mac. **No** la empaques en IPA de TestFlight/App Store.
- **TestFlight / sandbox de Apple** (sin cobro real): usa claves de **tienda** — **`appl_…`** (iOS) y **`goog_…`** (Android).
- La config **Firebase — prod** en VS Code **ya no** define RC; pon `appl_` / `goog_` en **`.env`** o **`.dart_defines`** al generar release / TestFlight.
- **Firebase — dev** sigue con `test_` de ejemplo solo para desarrollo local.
| `SENTRY_DSN` | Sentry | Dashboard Sentry → Proyecto → DSN |
| `MIXPANEL_TOKEN` | Mixpanel | Dashboard Mixpanel → Configuración → Token |

Para actualizar, edita `.vscode/launch.json` o pasa por línea de comandos:

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

---

### Secrets del servidor (quedan en Secret Manager de GCP)

Usados por las **Cloud Functions** en tiempo de ejecución. **Nunca en el código del app.**

| Secret | Usado por | Cómo obtener |
|--------|-----------|--------------|
| `REVENUECAT_WEBHOOK_KEY` | Webhook de suscripciones | 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 |

Para configurar o actualizar cada 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
```

> Cada comando pide el valor de forma interactiva. El valor **no aparece** en la terminal.

Para ver los secrets existentes:

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

---

## Internacionalización (i18n)

El app soporta **3 idiomas**: inglés (`en`), portugués (`pt`) y español (`es`).

### Cómo se elige el idioma

```
App abre
  ├─ ¿Tiene idioma guardado por el usuario? → usa el guardado
  └─ No → lee el idioma del dispositivo/navegador
            ├─ ¿Es en, pt o es? → usa ese idioma
            └─ No es ninguno → usa el idioma por defecto (base_locale)
```

### Cambiar idioma por defecto (fallback)

Cuando el dispositivo del usuario está en un idioma no soportado (ej: japonés, francés), el app usa el **idioma por defecto**. Por defecto es inglés. Para cambiar a portugués:

**`slang.yaml`**
```yaml
base_locale: pt   # cambiar aquí: en | pt | es
```

Luego ejecuta:
```sh
dart run slang
```

### Añadir o editar traducciones

Los archivos están en `lib/i18n/`:
- `en.i18n.json` — inglés
- `pt.i18n.json` — portugués
- `es.i18n.json` — español

Tras editar cualquier `.i18n.json`, siempre ejecuta `dart run slang` para regenerar `translations.g.dart`.

### Selector de idioma

El usuario puede cambiar el idioma en **Configuración → Idioma**. La elección se guarda en el dispositivo y se restaura en la próxima apertura del app.

---

## Webhook RevenueCat

El webhook recibe eventos de compra (nueva suscripción, renovación, cancelación) de RevenueCat.

**En el dashboard de RevenueCat:** Webhooks → añadir URL de la función → Authorization header = valor de `REVENUECAT_WEBHOOK_KEY`.

---

## Deploy

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

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

---

## Publicar en iOS (App Store)

Guía completa: [docs/ios-release.md](docs/ios-release.md)

```bash
kasy ios configure   # una vez — credenciales Apple
kasy ios release     # genera IPA y sube a App Store Connect
```

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

---

## Seguridad

El `.gitignore` ya excluye: `firebase_key.json`, `.env`, `.env.*`, `*.pem`, `*.keystore`, `.kasy/apple.env`, `.kasy/codemagic.env`.

Nunca subas credenciales al repositorio.
