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

9.9 KiB
Raw Blame History

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
  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:
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"
};
  1. 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

# 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

# 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:

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

cd functions
npm install @anthropic-ai/sdk
firebase deploy --only functions

7. Integrazione Angular

Installare dipendenze

npm install @angular/fire firebase

Configurare in app.config.ts (Angular 17+ standalone)

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

{
  "indexes": [
    {
      "collectionGroup": "meals",
      "queryScope": "COLLECTION",
      "fields": [
        { "fieldPath": "timestamp", "order": "DESCENDING" }
      ]
    }
  ],
  "fieldOverrides": []
}

.firebaserc

{
  "projects": {
    "default": "calorie-tracker-XXXXX"
  }
}

firebase.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