miinventario-v2/docs/02-integraciones/INT-004-firebase-fcm.md
rckrdmrd 1a53b5c4d3 [MIINVENTARIO] feat: Initial commit - Sistema de inventario con análisis de video IA
- Backend NestJS con módulos de autenticación, inventario, créditos
- Frontend React con dashboard y componentes UI
- Base de datos PostgreSQL con migraciones
- Tests E2E configurados
- Configuración de Docker y deployment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 02:25:48 -06:00

281 lines
5.8 KiB
Markdown

# INT-004: Integracion Firebase FCM
---
id: INT-004
type: Integration
status: Pendiente
version: "1.0.0"
created_date: 2026-01-10
updated_date: 2026-01-10
simco_version: "4.0.0"
---
## Metadata
| Campo | Valor |
|-------|-------|
| **ID** | INT-004 |
| **Servicio** | Firebase Cloud Messaging |
| **Proposito** | Notificaciones push |
| **Criticidad** | P1 |
| **Estado** | Pendiente |
---
## 1. Descripcion
Integracion con Firebase Cloud Messaging (FCM) para enviar notificaciones push a los usuarios sobre resultados de inventario, pagos y otros eventos.
---
## 2. Informacion del Servicio
| Campo | Valor |
|-------|-------|
| Proveedor | Google Firebase |
| Documentacion | https://firebase.google.com/docs/cloud-messaging |
| Consola | https://console.firebase.google.com |
| SDK | firebase-admin (node), @react-native-firebase/messaging |
---
## 3. Configuracion
### Variables de Entorno
```env
FIREBASE_PROJECT_ID=miinventario-xxx
FIREBASE_CLIENT_EMAIL=firebase-adminsdk@...
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n..."
```
### Instalacion Backend
```bash
npm install firebase-admin
```
### Instalacion Mobile
```bash
npm install @react-native-firebase/app @react-native-firebase/messaging
```
---
## 4. Tipos de Notificaciones
| Tipo | Evento | Prioridad |
|------|--------|-----------|
| INVENTORY_READY | Inventario procesado | Alta |
| PAYMENT_CONFIRMED | Pago confirmado | Alta |
| PAYMENT_PENDING | Voucher por vencer | Media |
| REFERRAL_ACTIVATED | Referido activado | Media |
| LOW_CREDITS | Creditos bajos | Baja |
| PROMO_ACTIVE | Promocion activa | Baja |
---
## 5. Implementacion Backend
### Inicializacion
```typescript
import * as admin from 'firebase-admin';
@Module({})
export class FirebaseModule {
static forRoot(): DynamicModule {
admin.initializeApp({
credential: admin.credential.cert({
projectId: process.env.FIREBASE_PROJECT_ID,
clientEmail: process.env.FIREBASE_CLIENT_EMAIL,
privateKey: process.env.FIREBASE_PRIVATE_KEY.replace(/\\n/g, '\n'),
}),
});
return {
module: FirebaseModule,
global: true,
};
}
}
```
### Servicio de Notificaciones
```typescript
@Injectable()
export class NotificationsService {
async sendToUser(
userId: string,
notification: { title: string; body: string; data?: Record<string, string> }
) {
const user = await this.usersService.findOne(userId);
if (!user.fcmToken) return;
await admin.messaging().send({
token: user.fcmToken,
notification: {
title: notification.title,
body: notification.body,
},
data: notification.data,
android: {
priority: 'high',
notification: {
channelId: 'default',
sound: 'default',
},
},
apns: {
payload: {
aps: {
sound: 'default',
badge: 1,
},
},
},
});
}
async sendToTopic(
topic: string,
notification: { title: string; body: string }
) {
await admin.messaging().sendToTopic(topic, {
notification,
});
}
}
```
---
## 6. Implementacion Mobile
### Configuracion
```typescript
// App.tsx
import messaging from '@react-native-firebase/messaging';
const requestPermission = async () => {
const authStatus = await messaging().requestPermission();
const enabled =
authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
if (enabled) {
const token = await messaging().getToken();
await api.updateFcmToken(token);
}
};
```
### Handlers
```typescript
// Foreground
messaging().onMessage(async remoteMessage => {
// Mostrar notificacion in-app
showLocalNotification(remoteMessage);
});
// Background/Quit
messaging().setBackgroundMessageHandler(async remoteMessage => {
// Procesar datos
console.log('Background message:', remoteMessage);
});
// Tap en notificacion
messaging().onNotificationOpenedApp(remoteMessage => {
// Navegar a pantalla
navigateToScreen(remoteMessage.data.screen);
});
```
---
## 7. Modelo de Datos
### Tabla: notification_tokens
```sql
CREATE TABLE notification_tokens (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
token VARCHAR(255) NOT NULL,
platform VARCHAR(20), -- 'ios', 'android'
device_info JSONB,
is_active BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
```
### Tabla: notification_logs
```sql
CREATE TABLE notification_logs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id),
type VARCHAR(50),
title VARCHAR(255),
body TEXT,
data JSONB,
sent_at TIMESTAMP DEFAULT NOW(),
delivered_at TIMESTAMP,
opened_at TIMESTAMP
);
```
---
## 8. Templates de Notificacion
```typescript
const NOTIFICATION_TEMPLATES = {
INVENTORY_READY: {
title: 'Inventario listo',
body: 'Tu inventario de {{storeName}} esta listo. {{totalItems}} productos detectados.',
},
PAYMENT_CONFIRMED: {
title: 'Pago confirmado',
body: 'Tu pago de ${{amount}} MXN fue confirmado. +{{credits}} creditos.',
},
REFERRAL_ACTIVATED: {
title: 'Referido activado',
body: '{{referredName}} activo su cuenta. +{{reward}} creditos.',
},
};
```
---
## 9. Testing
### Enviar Notificacion de Prueba
```bash
# Usando Firebase CLI
firebase messaging:send \
--token "device_token" \
--notification-title "Test" \
--notification-body "This is a test"
```
### Simulador iOS
FCM no funciona en simulador iOS. Usar dispositivo fisico o Expo Go.
---
## 10. Referencias
- [Firebase FCM Docs](https://firebase.google.com/docs/cloud-messaging)
- [React Native Firebase](https://rnfirebase.io/messaging/usage)
- [MII-005](../01-epicas/MII-005-procesamiento-ia.md) - Notificacion de resultado
---
**Ultima Actualizacion:** 2026-01-10