# 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 } ) { 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