Files
pingu-concerts/docs/wiki/Push-Notifications.md
T

42 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Push Notifications
## Umfang und Einstellungen
Automatische Android-Pushs gibt es für neue Freundschaftsanfragen, Direktnachrichten und Veranstaltungseinladungen. Allgemeine Konzertänderungen und Kommentare lösen keine Pushs aus. Manuelle Firebase-Kampagnen sind getrennt und beachten die MetalCircle-Einstellungen nicht.
`PUSH_ENABLED=false` ist der Standard. Erst nach [Firebase-Einrichtung](Firebase.md) wird der Versand aktiviert; während er deaktiviert ist, entstehen keine Versandaufträge für historische Aktivitäten.
Im eigenen Profil lassen sich die drei Kategorien getrennt einstellen. Die Einstellungen gelten für alle angemeldeten Android-Geräte des Kontos; Android muss zusätzlich Benachrichtigungen erlauben. Ausschalten verwirft ausstehende Meldungen dieser Kategorie. Die zuletzt bei Anmeldung, Geräteanmeldung oder Sprachwechsel gewählte Sprache wird pro Konto in `notification_preferences.language` gespeichert. Das Sprach-Dropdown bietet Deutsch und Englisch an und markiert die aktuelle Sprache.
Pushs enthalten generische Texte, etwa „Neue Nachricht Du hast eine neue Nachricht.“ Namen, Nachrichtentext und Veranstaltungstitel werden nicht auf den Sperrbildschirm übertragen. Android erhält eine zufällige Versandkennung und die Bindung an die aktuelle Sitzung. Im Vordergrund zeigt die WebView einen Hinweis zum Öffnen an; Capacitor Push Notifications 6.0.5 erzeugt mit dem konfigurierten `presentationOptions: ['sound', 'alert']` zusätzlich eine native Notification. Im Hintergrund übernimmt Firebase/Android die Systembenachrichtigung. Android-Berechtigung und Kanal-Einstellungen gelten in beiden Fällen.
Alle drei Arten verwenden denselben kombinierten `notification`-/`data`-Payload: generischer Titel/Text, `notification_id` und `session_tag`, hohe Android-Priorität, fünf Minuten TTL, `ic_notification`, Standardton und private Sichtbarkeit. Der Tag entspricht der Outbox-UUID; Wiederholungen ersetzen dieselbe Meldung, verschiedene Aufträge haben unterschiedliche Tags. Es gibt weder einen eigenen Kanal noch eine besondere `click_action` für Direktnachrichten. Da Payload und Manifest keinen Channel angeben, wird der Firebase-Fallback-Kanal verwendet. Die Capacitor-Tap-Verarbeitung löst das Ziel über `/notifications/{id}` auf.
Ein Chat-Aufruf setzt eingegangene Nachrichten sofort auf gelesen. Geschieht dies vor dem Worker-Versand, wird die Meldung absichtlich verworfen; nach dem Versand kann ein späterer Tap wegen bereits gelesenem Ziel zur Übersicht führen. Deshalb beim Smoke-Test den Chat von B bis zur Erfassung der Notification geschlossen halten. Der historische DM-Test wurde durch Nutzerbeobachtung/Tap bestätigt, aber nicht ebenso zuverlässig im Notification Manager erfasst wie die anderen Arten. Daraus lässt sich kein belegter DM-spezifischer Versandfehler ableiten; in Pre-Production muss der technische Nachweis für alle drei Arten erneut erfolgen.
Beim Antippen prüft die App die Sitzung. `/notifications/{id}` prüft erneut Empfänger, Sitzung und Berechtigung und leitet zur Unterhaltung, Anfrage oder Veranstaltung weiter. Bereits gelesene Nachrichten, erledigte Anfragen, entfernte Einladungen oder blockierte Kontakte führen zur Übersicht.
## Versand und Fehlerfälle
Aktivität und Versandauftrag werden in derselben PostgreSQL-Transaktion gespeichert. Ein Hintergrund-Thread im FastAPI-Prozess verarbeitet `push_notifications`; ein zusätzlicher Broker oder Container ist nicht nötig. Mehrere Prozesse reservieren Aufträge über Zeilensperren und `SKIP LOCKED`.
Aufträge entstehen nur für aktuell registrierte Geräte. Sie enthalten Geräte-/Session-Referenzen und einen Token-Fingerabdruck, keine Klartext-Tokens oder Nachrichteninhalte. Vor Versand werden Kategorie, Blockierungen, offener/ungelesener Zustand, Berechtigungen, Token und Sitzung geprüft. Geräte-/Session-Sperren koordinieren den Versand mit Logout und Tokenänderungen. Logout löscht Zuordnungen und Aufträge über Fremdschlüssel.
Firebase Admin SDK 7.1.0 sendet über FCM. Vorübergehende Fehler und Konfigurationsfehler erhalten maximal drei Wiederholungen nach 60, 120 und 240 Sekunden. Nach vier Versuchen wird der Auftrag als fehlgeschlagen markiert. Nicht registrierte Tokens werden entfernt; Projekt-/Authentifizierungsfehler löschen keine Geräte. Logs enthalten nur feste Fehlerkategorien.
Aufträge verfallen nach einer Stunde; FCM erhält fünf Minuten Gültigkeit. Der laufende Worker bereinigt Metadaten nach sieben Tagen (keine Bereinigung, solange er deaktiviert ist). Bei einem Prozessabbruch nach Firebase-Annahme und vor DB-Commit sind Doppelzustellungen nicht vollständig auszuschließen; die stabile Android-Kennung ersetzt Wiederholungen im Benachrichtigungsbereich.
Bereits zugestellte Meldungen lassen sich serverseitig nicht zurückrufen. Die App leert eigene Benachrichtigungen beim Sitzungswechsel; generische Texte und Zielprüfung schützen zusätzlich. Ein kleiner Zeitraum zwischen letzter Berechtigungsprüfung und Netzwerkzustellung bleibt technisch bestehen.
## Tests und verifizierter Gerätetest
Automatisierte Tests nutzen isolierte lokale PostgreSQL-Schemas und simuliertes Firebase; sie senden keine echten Pushs. Sie prüfen unter anderem DE/EN, Kategorie-Abwahl, private Nachrichtentexte, Logout/Benutzerwechsel, Tokenwechsel, ungültige Tokens und Fehlerbehandlung.
Der echte lokale FCM-E2E-Test wurde am **15.09.2026** mit dem Android-Gerät und dem lokalen Backend erfolgreich abgeschlossen. Freundschaftsanfrage, Direktnachricht und Veranstaltungseinladung erreichten das Gerät. Freundschaftsanfrage und Einladung wurden im Android Notification Manager bestätigt; bei der Direktnachricht öffnete Antippen der Benachrichtigung den Chat. Die Push-Vorschauen blieben generisch. Für IAM, Firebase-Projekt und Secret-Mount siehe [Firebase](Firebase.md). Der Test fand lokal statt; Cloud-Staging und Produktion waren nicht betroffen.
Ein [fertiger ChatGPT-Prompt](Firebase-Setup-Prompt.md) begleitet die Einrichtung.
## Pre-Production Deployment
[Firebase → Pre-Production Deployment](Firebase.md#pre-production-deployment) beschreibt die vorbereitete Compose-Konfiguration, den ausschließlich dort verwendeten Service Account, Secret-Mount und Offline-Preflight sowie den Smoke-Test einschließlich Direktnachrichten und sicherer Gerätebeobachtung. Ein erfolgreicher SDK-Aufruf allein ist kein Android-Empfangsnachweis.