Files
traccia-calorica/docs/FIRESTORE_SETUP.md
emanuele 7fd03a99ba chore: initial project setup with documentation and design assets
Add project foundation: CLAUDE.md, requirements tracking system,
technical architecture docs, Firestore setup guide, device testing guide,
and Stitch design mockups for Precision Vitality app.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-16 09:44:35 +02:00

350 lines
9.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Guida Configurazione Firebase & Firestore
> Guida passo-passo per configurare Firebase, Firestore e Cloud Functions per CalorieTracker.
> Ultimo aggiornamento: 16/04/2026
---
## 1. Creazione Progetto Firebase
### Passo 1 — Console Firebase
1. Andare su [console.firebase.google.com](https://console.firebase.google.com)
2. Cliccare "Aggiungi progetto"
3. Nome progetto: `calorie-tracker` (o simile disponibile)
4. **Disabilitare** Google Analytics (non necessario per ora)
5. Cliccare "Crea progetto"
### Passo 2 — Aggiungere App Web
1. Nella dashboard progetto, cliccare l'icona **Web** (`</>`)
2. Nome app: `CalorieTracker Web`
3. **Non** abilitare Firebase Hosting (non necessario)
4. Copiare la configurazione Firebase:
```javascript
const firebaseConfig = {
apiKey: "AIza...",
authDomain: "calorie-tracker-XXXXX.firebaseapp.com",
projectId: "calorie-tracker-XXXXX",
storageBucket: "calorie-tracker-XXXXX.appspot.com",
messagingSenderId: "123456789",
appId: "1:123456789:web:abcdef"
};
```
5. Salvare questi valori in `environment.ts` e `environment.prod.ts`
---
## 2. Abilitare Firestore
### Passo 1 — Creare Database
1. Nel menu laterale Firebase: **Build → Firestore Database**
2. Cliccare "Crea database"
3. Selezionare località: **europe-west1 (Belgio)** — più vicino all'Italia
4. Selezionare "Inizia in modalità produzione"
5. Cliccare "Abilita"
### Passo 2 — Regole di Sicurezza
Nella tab **Regole** di Firestore, incollare:
```
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
// Nessun accesso di default
match /{document=**} {
allow read, write: if false;
}
// Accesso pasti: solo utente proprietario
match /users/{userId}/meals/{mealId} {
allow read, write: if request.auth != null
&& request.auth.uid == userId;
// Validazione scrittura
allow create: if request.auth != null
&& request.auth.uid == userId
&& request.resource.data.calories is number
&& request.resource.data.calories > 0
&& request.resource.data.calories <= 9999
&& request.resource.data.inputType in ['manual', 'llm']
&& request.resource.data.timestamp is timestamp
&& request.resource.data.createdAt is timestamp;
allow update: if request.auth != null
&& request.auth.uid == userId;
allow delete: if request.auth != null
&& request.auth.uid == userId;
}
}
}
```
### Passo 3 — Indici
Nella tab **Indici** di Firestore, creare indice composto:
| Collection | Campi | Query Scope |
|------------|-------|-------------|
| `users/{userId}/meals` | `timestamp` DESC | Collection |
> **Nota**: Firestore creerà automaticamente gli indici necessari quando l'app esegue le prime query. In alternativa, il file `firestore.indexes.json` nel progetto definisce gli indici programmaticamente.
---
## 3. Abilitare Authentication
### Passo 1 — Anonymous Auth
1. Nel menu laterale: **Build → Authentication**
2. Cliccare "Inizia"
3. Tab **Metodo di accesso**
4. Abilitare **Anonimo** → switch ON → Salva
### Passo 2 — (Futuro) Google Sign-In
> Per upgrade futuro da Anonymous a Google Sign-In:
> 1. Abilitare provider "Google" in Authentication
> 2. Configurare OAuth consent screen in Google Cloud Console
> 3. Implementare linking account (da anonimo a Google)
---
## 4. Configurazione App Android
### Passo 1 — Aggiungere App Android
1. Dashboard Firebase → "Aggiungi app" → icona Android
2. Package name: `com.precisionvitality.app` (deve corrispondere a `capacitor.config.ts`)
3. App nickname: `CalorieTracker Android`
4. SHA-1: (opzionale per ora, necessario per Google Sign-In)
### Passo 2 — Scaricare google-services.json
1. Scaricare `google-services.json`
2. Copiare in `android/app/google-services.json` (dopo `npx cap add android`)
---
## 5. Configurazione App iOS
### Passo 1 — Aggiungere App iOS
1. Dashboard Firebase → "Aggiungi app" → icona iOS
2. Bundle ID: `com.precisionvitality.app`
3. App nickname: `CalorieTracker iOS`
### Passo 2 — Scaricare GoogleService-Info.plist
1. Scaricare `GoogleService-Info.plist`
2. Copiare in `ios/App/App/GoogleService-Info.plist` (dopo `npx cap add ios`)
---
## 6. Setup Firebase Cloud Functions (Proxy AI)
### Passo 1 — Upgrade a Blaze Plan (Pay-as-you-go)
> **ATTENZIONE**: Le Cloud Functions richiedono il piano Blaze (pay-as-you-go).
> Il piano Blaze include comunque il tier gratuito di Firestore e Auth.
> Non ci saranno costi se il traffico resta nel free tier.
1. Console Firebase → icona ingranaggio → Utilizzo e fatturazione
2. Upgrade a Blaze
3. Impostare budget alert: $5/mese
### Alternativa gratuita: Se non si vuole il piano Blaze
- Usare un backend NestJS su VPS esistente come proxy
- Oppure usare Cloudflare Workers (free tier: 100k req/giorno)
### Passo 2 — Inizializzare Cloud Functions
```bash
# Nella root del progetto
npm install -g firebase-tools
firebase login
firebase init functions
# Selezionare:
# - Linguaggio: TypeScript
# - ESLint: Sì
# - Installare dipendenze: Sì
```
### Passo 3 — Configurare Secret per API Key
```bash
# Salvare API key come secret (non in codice!)
firebase functions:secrets:set ANTHROPIC_API_KEY
# Inserire: sk-ant-...
```
### Passo 4 — Implementare la Function
File `functions/src/index.ts`:
```typescript
import { onRequest } from 'firebase-functions/v2/https';
import { defineSecret } from 'firebase-functions/params';
import Anthropic from '@anthropic-ai/sdk';
const anthropicKey = defineSecret('ANTHROPIC_API_KEY');
export const estimateCalories = onRequest(
{
cors: true,
region: 'europe-west1',
secrets: [anthropicKey],
timeoutSeconds: 15,
memory: '256MiB',
},
async (req, res) => {
// Verificare metodo POST
if (req.method !== 'POST') {
res.status(405).send('Method Not Allowed');
return;
}
// Verificare auth token
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith('Bearer ')) {
res.status(401).send('Unauthorized');
return;
}
// Estrarre e validare input
const { description } = req.body;
if (!description || typeof description !== 'string' || description.length > 500) {
res.status(400).send('Invalid description');
return;
}
try {
const client = new Anthropic({ apiKey: anthropicKey.value() });
const message = await client.messages.create({
model: 'claude-haiku-4-5-20251001',
max_tokens: 256,
system: `Sei un nutrizionista. Stima le calorie del pasto descritto.
Rispondi SOLO con JSON: {"calories": number, "confidence": "high"|"medium"|"low", "explanation": "string"}`,
messages: [{ role: 'user', content: description }],
});
// Parsare risposta
const text = message.content[0].type === 'text' ? message.content[0].text : '';
const jsonStr = text.replace(/```json?\n?/g, '').replace(/```/g, '').trim();
const result = JSON.parse(jsonStr);
res.json(result);
} catch (error) {
console.error('Estimation error:', error);
res.status(500).json({ error: 'Estimation failed' });
}
}
);
```
### Passo 5 — Deploy
```bash
cd functions
npm install @anthropic-ai/sdk
firebase deploy --only functions
```
---
## 7. Integrazione Angular
### Installare dipendenze
```bash
npm install @angular/fire firebase
```
### Configurare in app.config.ts (Angular 17+ standalone)
```typescript
import { provideFirebaseApp, initializeApp } from '@angular/fire/app';
import { provideFirestore, getFirestore, enableIndexedDbPersistence } from '@angular/fire/firestore';
import { provideAuth, getAuth } from '@angular/fire/auth';
import { environment } from '../environments/environment';
export const appConfig: ApplicationConfig = {
providers: [
provideFirebaseApp(() => initializeApp(environment.firebase)),
provideFirestore(() => {
const firestore = getFirestore();
enableIndexedDbPersistence(firestore);
return firestore;
}),
provideAuth(() => getAuth()),
// ... altri providers
]
};
```
---
## 8. File di Configurazione Locale
### `firestore.rules` (nella root del progetto)
Copiare le regole dal Passo 2 della Sezione 2.
### `firestore.indexes.json`
```json
{
"indexes": [
{
"collectionGroup": "meals",
"queryScope": "COLLECTION",
"fields": [
{ "fieldPath": "timestamp", "order": "DESCENDING" }
]
}
],
"fieldOverrides": []
}
```
### `.firebaserc`
```json
{
"projects": {
"default": "calorie-tracker-XXXXX"
}
}
```
### `firebase.json`
```json
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"source": "functions",
"runtime": "nodejs18"
}
}
```
---
## 9. Limiti Free Tier Firebase (Spark / Blaze)
| Risorsa | Limite Gratuito | Note |
|---------|----------------|------|
| Firestore letture | 50.000/giorno | ~1.600 utenti × 30 letture/giorno |
| Firestore scritture | 20.000/giorno | ~2.000 utenti × 10 pasti/giorno |
| Firestore storage | 1 GiB | Sufficiente per ~5M documenti pasto |
| Auth utenti | Illimitati | Anonymous + email + social |
| Cloud Functions invocazioni | 2M/mese | ~66.000/giorno |
| Cloud Functions compute | 400.000 GB-secondi/mese | Sufficiente per proxy AI |
---
## 10. Checklist Configurazione
- [ ] Progetto Firebase creato
- [ ] Firestore abilitato (europe-west1)
- [ ] Regole sicurezza configurate
- [ ] Anonymous Auth abilitato
- [ ] App Web registrata + config copiata
- [ ] App Android registrata + google-services.json scaricato
- [ ] (Opzionale) App iOS registrata + GoogleService-Info.plist scaricato
- [ ] Cloud Functions inizializzate
- [ ] ANTHROPIC_API_KEY salvata come secret
- [ ] Cloud Function deployata
- [ ] @angular/fire installato e configurato
- [ ] Test lettura/scrittura funzionante
- [ ] Offline persistence verificata