Skip to main content

Notifications et Push

Vue d’ensemble

Le système de notifications UnikSim combine trois mécanismes complémentaires : une inbox persistée dans Redis, des événements temps réel via Socket.IO, et des push notifications via Firebase Cloud Messaging (FCM). L’objectif est de garantir qu’une notification puisse être visible immédiatement dans l’application lorsque l’utilisateur est connecté, tout en permettant une livraison push lorsque l’application n’est pas active.

1. Architecture générale des notifications

flowchart LR
    SRC[Services métier / SupportService] --> NS[NotificationService]

    NS --> REDIS[(Redis inbox)]
    NS --> EVT[EventEmitter]
    NS --> FBS[FirebaseService]

    EVT --> GW[SupportGateway]
    GW --> ROOM[user_userId]
    ROOM --> FE[Frontend Angular / App]

    FBS --> TOK[UserFcmToken + subscriptions]
    FBS --> FCM[Firebase FCM]
    FCM --> DEV[Appareils utilisateur]

    FE --> API[API notifications]
    API --> REDIS

La persistance Redis et l’envoi FCM sont traités comme deux canaux distincts. Une erreur de push ne supprime donc pas la notification de l’inbox.

2. Création d’une notification pour un utilisateur connecté

sequenceDiagram
    participant S as Service métier
    participant N as NotificationService
    participant R as Redis
    participant E as EventEmitter
    participant G as SupportGateway
    participant F as Frontend

    S->>N: notifyUser(userId, type, payload)
    N->>N: Construit titre/body localisés
    N->>R: LPUSH notification + expiry
    R-->>N: Persistée
    N->>E: NOTIFICATION_CREATED
    E->>G: événement
    G-->>F: notification.created
    F->>F: upsert dans l'état local
    F->>F: incrémente unread + joue le son

Le gateway relaie l’événement dans la room du compte utilisateur. Le frontend peut ainsi mettre à jour l’interface immédiatement sans attendre un prochain GET.

3. Livraison Push via Firebase

sequenceDiagram
    participant N as NotificationService
    participant FBS as FirebaseService
    participant DB as MySQL
    participant FCM as Firebase Cloud Messaging
    participant D as Appareil

    N->>FBS: sendPushNotificationToUser(userId)
    FBS->>DB: Charge installations FCM de l'utilisateur
    DB-->>FBS: tokens actifs
    FBS->>FCM: multicast(tokens, payload)
    FCM-->>D: push notification
    FCM-->>FBS: résultats par token
    FBS->>FBS: détecte invalid/unregistered
    FBS->>DB: supprime installations/tokens invalides

Les push sont envoyées à toutes les installations du compte. Pour les notifications liées à un jeu, le backend peut cibler les installations selon leurs subscriptions à des productCodeId.

4. Installations FCM et subscriptions

flowchart TD
    APP[Application / appareil] --> REG[registerInstallation]
    REG --> OWN[Validation des productCodeIds possédés]
    OWN --> CLEAN[Supprime le même token d'anciennes installations]
    CLEAN --> UPSERT[Upsert UserFcmToken]
    UPSERT --> SUB[Remplace UserFcmSubscriptions]

    SUB --> SEND[Envoi futur]
    SEND --> MATCH[Filtre ownership + productCodeId]
    MATCH --> TOKENS[Liste des tokens]
    TOKENS --> FCM[Firebase FCM]
    FCM --> BAD{Token invalide ?}
    BAD -->|Oui| DEL[Supprime token + subscriptions]
    BAD -->|Non| OK[Conserve installation]

5. Cycle de vie d’une notification

stateDiagram-v2
    [*] --> CREATED
    CREATED --> UNREAD: persistance Redis
    UNREAD --> READ: POSTmarquer /notifications/:uid/readcomme lue
    READ --> UNREAD: nouvelle notification distincte
    UNREAD --> DELETED: DELETE /notifications/:uidsupprimer
    READ --> DELETED: DELETE /notifications/:uidsupprimer
    DELETED --> [*]

Architecture frontend

Le frontend maintient une copie locale de l’inbox et fusionne les données provenant de l’API HTTP avec les événements temps réel. Le service principal est user-notification.service.ts.

flowchart LR
    API[GET /notifications] --> UNS[UserNotificationService]
    SOCK[SupportSocketService] -->|notification.created| UNS
    UNS --> STATE[BehaviorSubject notifications]
    STATE --> UI[Badge / liste / toast]

    UI -->|mark as read| READ[POST /notifications/:uid/read]
    UI -->|delete| DEL[DELETE /notifications/:uid]
    READ --> UNS
    DEL --> UNS

Responsabilités du frontend

  • charger l’inbox initiale avec GET /notifications;
  • fusionner une notification temps réel avec la liste locale via son UID;
  • maintenir un unread count dérivé;
  • marquer une notification comme lue;
  • supprimer une notification;
  • afficher les nouvelles notifications reçues par Socket.IO immédiatement.

Persistance Redis

L’inbox d’un utilisateur est stockée dans une liste Redis dont la clé est dérivée de son identifiant. Les nouvelles notifications sont insérées en tête via LPUSH et la clé reçoit une durée de rétention.

Les opérations read/unread/delete utilisent la liste existante et modifient ou retirent l’entrée concernée.

Notifications liées à un jeu

Le système possède également un chemin de notification lié à un jeu. Avant l’envoi, le backend vérifie que les subscriptions FCM sont toujours cohérentes avec les product codes réellement possédés. Cela évite d’envoyer une notification de jeu à un appareil dont l’accès a été retiré ou réassigné.

Gestion des erreurs

  • Une erreur FCM ne doit pas supprimer une notification déjà persistée dans Redis.
  • Les tokens invalides ou désenregistrés sont nettoyés après le résultat FCM.
  • Les erreurs de persistance, temps réel et push sont journalisées séparément.
  • La diffusion temps réel dépend du gateway; l’inbox reste récupérable ensuite via HTTP.

Fichiers principaux

  • uniksim-back-end/src/service/notification.service.ts
  • uniksim-back-end/src/service/firebase.service.ts
  • uniksim-back-end/src/gateway/support.gateway.ts
  • uniksimFrontEnd/src/app/service/notifications/user-notification.service.ts
  • uniksimFrontEnd/src/app/service/support/support-socket.service.ts

Points d’attention

  • La notification doit être persistée avant d’être émise en temps réel.
  • L’inbox Redis et le push FCM sont des canaux indépendants.
  • Les subscriptions de jeu doivent être validées contre l’ownership courant.
  • Les tokens FCM invalides doivent être nettoyés pour éviter des envois inutiles répétés.
  • Le frontend doit dédupliquer les notifications temps réel par UID.