Notifications Push

Cette section détaille le système de notifications push utilisant Firebase Cloud Messaging (FCM) pour envoyer des notifications aux utilisateurs mobiles.

FirebaseMessagingService (firebase-messaging.service.ts)

Service qui gère l'envoi de notifications push via Firebase Cloud Messaging.

Propriétés

Méthodes principales

async sendNotificationToUser(firebaseUid: string, notification: NotificationPayload)

Description : Envoie une notification push à un utilisateur spécifique.
Paramètres :

Flux :

  1. Récupère l'utilisateur via UserService
  2. Récupère les tokens FCM de l'utilisateur
  3. Envoie la notification à tous les tokens
  4. Gère les tokens invalides/expirés

Retour : Promise<void>

async sendNotificationToTokens(tokens: string[], notification: NotificationPayload)

Description : Envoie une notification à une liste de tokens FCM.
Paramètres :

Actions :

Retour : Promise<void>

async removeInvalidToken(firebaseUid: string, token: string)

Description : Retire un token FCM invalide de l'utilisateur.
Retour : Promise<void>

Structure NotificationPayload

{
    title: string,          // Titre de la notification
    body: string,           // Corps du message
    imageUrl?: string,      // URL d'image (optionnel)
    data?: {                // Données custom (optionnel)
        [key: string]: string
    }
}

Enregistrement des Tokens FCM

Endpoint

POST /api/user/fcm-token

Description : Enregistre un token FCM pour un utilisateur.
Body :

{ fcmToken: string }

Actions :

  1. Valide le token (non vide)
  2. Récupère l'utilisateur
  3. Ajoute le token à user.fcmTokens[] (si pas déjà présent)
  4. Sauvegarde dans MongoDB

Réponse :

{
    success: true,
    message: 'FCM token registered successfully'
}

Gestion multi-device

Un utilisateur peut avoir plusieurs tokens FCM :

Cas d'utilisation

1. Demande d'ami

Déclencheur : Un utilisateur envoie une demande d'ami

Notification :

{
    title: 'Nouvelle demande d\'ami',
    body: `${senderUsername} vous a envoyé une demande d'ami`,
    data: {
        type: 'friend_request',
        senderUid: senderFirebaseUid
    }
}

Service : FriendsService.sendFriendRequest()

2. Demande acceptée

Déclencheur : Un utilisateur accepte une demande d'ami

Notification :

{
    title: 'Demande d\'ami acceptée',
    body: `${accepterUsername} a accepté votre demande d'ami`,
    data: {
        type: 'friend_accepted',
        accepterUid: accepterFirebaseUid
    }
}

Service : FriendsService.acceptFriendRequest()

3. Nouveau message (futur)

Déclencheur : Nouveau message dans un canal

Notification :

{
    title: `Nouveau message dans ${channelName}`,
    body: `${authorUsername}: ${messagePreview}`,
    data: {
        type: 'new_message',
        channelId: channelId
    }
}

Service : ChatSocketService.handleSendMessage()

Gestion des erreurs

Tokens invalides

Lorsque FCM retourne une erreur pour un token :

Actions :

  1. Log de l'erreur
  2. Suppression du token via removeInvalidToken()
  3. Mise à jour de l'utilisateur dans MongoDB

Erreurs d'envoi

Types d'erreurs :

Gestion :

Configuration

Variables d'environnement

FIREBASE_PROJECT_ID=your_project_id
FIREBASE_PRIVATE_KEY=your_private_key
FIREBASE_CLIENT_EMAIL=your_client_email
FCM_SERVER_KEY=your_fcm_server_key (optionnel)

Firebase Admin SDK utilise les credentials du service account pour envoyer les notifications.

Initialisation Firebase Admin

import * as admin from 'firebase-admin';

admin.initializeApp({
    credential: admin.credential.cert({
        projectId: process.env.FIREBASE_PROJECT_ID,
        privateKey: process.env.FIREBASE_PRIVATE_KEY,
        clientEmail: process.env.FIREBASE_CLIENT_EMAIL
    })
});

Intégration Mobile (Flutter)

Installation (côté mobile)

  1. Ajouter firebase_messaging au pubspec.yaml
  2. Configurer Firebase dans l'app Flutter
  3. Demander permissions de notifications

Récupération du token

final fcmToken = await FirebaseMessaging.instance.getToken();
// Envoyer au serveur via POST /api/user/fcm-token

Écoute des notifications

FirebaseMessaging.onMessage.listen((RemoteMessage message) {
    // Notification reçue en foreground
    print('Message data: ${message.data}');
    if (message.notification != null) {
        print('Notification: ${message.notification!.title}');
    }
});

FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
    // Notification tapée (app en background)
    print('A new onMessageOpenedApp event was published!');
});

Gestion de l'action

Basé sur data.type, l'app mobile navigue vers :

Permissions

Android

Automatique depuis Android 13 (Tiramisu)

iOS

Demande explicite à l'utilisateur :

NotificationSettings settings = await FirebaseMessaging.instance.requestPermission(
    alert: true,
    badge: true,
    sound: true,
);

Limites FCM

Quotas gratuits

Taille du payload

Durée de vie

Sécurité

Validation des tokens

Données sensibles

Authentification

Notifications en temps réel vs Push

FCM (push)

Stratégie : Utiliser les deux en parallèle

Extensions possibles

Notifications groupées

Notifications riches

Notifications planifiées

Analytics

Topics