Skip to main content

Notifications et Push

Vérifié le 30 septembre 2026 sur le checkout local uniksimweb, branche messagerie_fixes, HEAD 3f74bcb0, incluant les changements indexés du refactoring temps réel. Cette description porte sur le code local; elle ne confirme pas son déploiement.

Vue d’ensemble

Toutes les notifications passent par NotificationService.notify(userId, notificationType, payload, isImportant). Le systèmecompte reçoit une entrée dans son inbox Redis, un événement Socket.IO sur /account et une tentative de notificationspush UnikSimFCM combinevers troisses mécanismesinstallations. complémentairesLe : une inbox persistée dans Redis, des événements temps réel via Socket.IO,Web et l’application mobile lisent l’inbox; le jeu produit des push notifications via Firebasel’API.

Cloud Messaging (FCM). L’objectif est

Flux de garantircréation qu’uneet 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 notificationsresponsabilités

flowchart LR
SRC[ServicesS[Service métier /ou SupportService]GameNotificationService] --> NS[NotificationService]N[NotificationService.notify]
NSN --> REDIS[R[(Inbox Redis inbox)du compte)]
NSN --> EVT[EventEmitter]E[EventEmitter NSnotification.created]
E --> FBS[FirebaseService]G[AccountGateway EVT/account]
G --> GW[SupportGateway]A[AccountSocketService]
GWA --> ROOM[user_userId]U[UserNotificationService ROOMet interface]
N --> FE[FrontendF[FirebaseService]
Angular / App]

    FBSF --> TOK[UserFcmTokenT[(UserFcmToken)]
+ subscriptions]
    FBSF --> FCM[Firebase FCM]
    D[FCM -->vers DEV[Appareilsinstallations utilisateur]du FE --> API[API notifications]
    API --> REDIS
compte]

La

persistanceVérifier Redisque le compte destinataire existe. Construire l’enveloppe avec UID unique, puis sauvegarder l’inbox. Émettre notification.created; AccountGateway relaie la notification vers user_<userId> dans le namespace /account. Construire le titre et l’envoile FCMcorps sontlocalisés, traitéspuis commetenter deuxle canaux distincts.push. Une erreur de push neest supprimejournalisée doncsans pasannuler lal’entrée notificationdéjà sauvegardée.

Contrat partagé

NotificationDto côté backend et UserNotification côté Angular partagent les champs uid, userId, notificationType, timestamp, isRead, isImportant. Les champs métier, par exemple ticketId ou simUid, sont placés directement à côté de l’inbox.cette enveloppe. Les champs d’enveloppe définis par le serveur écrasent ceux du payload.

2.

L’UID Créationcombine d’unele notificationcompte, le timestamp et quatre octets aléatoires pour undistinguer utilisateurplusieurs connecténotifications

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énementcréées dans la roommême milliseconde. Le texte push utilise les clés uniksim.push_<type>_title/body, les placeholders du payload et un texte de secours. Les valeurs FCM sont converties en chaînes; notificationUid conserve la compatibilité avec les clients historiques.

Inbox Redis et API du compte

La clé est user_<id>_notifications. LPUSH conserve les plus récentes en premier, LTRIM limite l’inbox à 100 entrées et EXPIRE fixe 10 519 200 secondes de rétention. Chaque insertion renouvelle le TTL de toute la liste; ce n’est pas une expiration indépendante par notification.

Action Endpoint Comportement Charger GET /notifications Retourne l’inbox du compte utilisateur.authentifié. Le frontendpeutLu ainsi/ mettrenon lu POST /notifications/:notificationUid/read Met à jour l’interfaceentrée immédiatementpar sansUID attendreavec unLSET. prochain GET. Supprimer DELETE /notifications/:notificationUid Retire l’entrée avec LREM.

Ces routes utilisent AuthGuardUser et l’identité request.user.sub.

3.Frontend Livraisonet Pushtemps via Firebaseréel

sequenceDiagramAccountSocketService participantreçoit Nnotification.created, asdéclenche NotificationServicele participantson FBSet asexpose FirebaseServicel’observable. participantAppComponent DBtransmet asla MySQLnotification participantà FCMUserNotificationService.upsert(). asCe Firebaseservice Cloudmaintient Messagingle participantBehaviorSubject, Ddéduplique aspar AppareilUID N->>FBS:et sendPushNotificationToUser(userId)dérive FBS->>DB:le Charge installations FCMnombre de l'utilisateurnotifications DB-->>FBS:non tokenslues. actifsLe FBS->>FCM:chargement multicast(tokens,initial payload)et FCM-->>D:les pushactions notificationlu/suppression FCM-->>FBS:utilisent résultatsHTTP. parSupportSocketService gère les conversations et tickets; la réception des notifications appartient au service du compte.

Installations et livraison FCM

PUT /push/installations/:installationId enregistre token et platform pour le compte authentifié. Dans une transaction, le service supprime les inscriptions périmées portant le même token FBS->>FBS:puis détectecrée invalid/unregisteredou FBS->>DB:met supprimeà jour UserFcmToken. DELETE /push/installations/tokens:installationId invalidesretire

l’installation de ce compte.

LesLa pushlivraison sont envoyées àcharge toutes les installations du compte.compte, Pourdéduplique les notificationstokens liées à un jeu, le backend peut cibleret 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: marquer comme lue
    READ --> UNREAD: nouvelle notification distincte
    UNREAD --> DELETED: supprimer
    READ --> DELETED: supprimer
    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çuesenvoie 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êtelots via LPUSHsendEachForMulticast. 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 entraînent la suppression de leurs installations. Le modèle actuel ne contient plus UserFcmSubscription ni de filtrage des appareils par productCode. Si les variables Firebase sont nettoyés aprèsabsentes, le résultat FCM. Les erreurs de persistance, temps réel et push sontest journaliséesdésactivé séparément. La diffusion temps réel dépend du gateway;mais l’inbox reste récupérableutilisable. ensuite

      Notifications viaenvoyées HTTP.

      par le jeu

      POST /saveNotification reçoit userUid (profil jeu du destinataire), notificationType, extraData et éventuellement isImportant. GameNotificationService traduit le profil actif ProductsCode.gameOid en compte Web et vérifie la simulation BrainCloud indiquée par extraData.simUid.

      L’expéditeur doit posséder un profil actif membre de cette simulation; le destinataire doit aussi en être membre. Le serveur utilise teacherUid et les clés de students du document pour cette vérification. Les types réservés au support sont refusés, le payload JSON est limité à 2 048 caractères et les identifiants à 255 caractères. La vérification BrainCloud expire après dix secondes. Une fois validée, la notification suit exactement le flux commun notify().

      Fichiers principaux

      • uniksim-back-end/src/service/notification.service.ts
      , uniksim-back-end/src/service/game-notification.service.ts, firebase.service.ts uniksim-back-end/src/dto/notification.dto.ts, src/gateway/support.account.gateway.ts, src/guards/socketAuth.middleware.ts uniksimFrontEnd/src/app/app.controller.ts et NOTIFICATION_CONFIG dans src/node.js/server/constantsVariable.js Angular : service/account/account-socket.service.ts, service/realtime/realtime-socket.ts, service/notifications/user-notification.service.ts, Models/Notification.ts Tests : uniksimFrontEnd/src/app/service/support/support-socket.test/notification/notification.service.test.ts et game-notification.service.test.ts

      Points

      Voir d’attentionaussi

        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 notificationsSupport temps réel par UID. .