Le notifiche iOS possono perdere il permesso di push se la notifica viene soppressa. Il codice di Discourse è configurato per sopprimere facoltativamente le notifiche e, di conseguenza, perderà il permesso di push quando ciò accade tre volte.
Ecco il codice per il service worker delle notifiche push.
Questo codice presenta un bug critico, alla riga 178. Lì, il service worker controlla se l’utente è attivo (cioè non inattivo). In tal caso, l’evento push restituisce false senza mostrare una notifica.
(Controlla anche payload.hide_when_active, ma a quanto pare hide_when_active è sempre true, e quindi questo codice restituisce sempre false quando l’utente è attivo.)
Apple vieta i push silenziosi, revocando il permesso di push dopo tre eventi che non mostrano notifiche
Ciò non è accettabile secondo le regole di Apple per le notifiche push.
Potenza e privacy
Sia il progetto open source WebKit che Apple trattano la privacy come un diritto umano fondamentale. Come per altre funzionalità privilegiate della piattaforma web, la richiesta di un abbonamento push richiede un gesto esplicito dell’utente. Richiede inoltre di impostare il flag
userVisibleOnlysu true e di mantenere tale promessa mostrando sempre una notifica in risposta a un messaggio push.L’API Web Push non è un invito per un runtime silenzioso in background, poiché ciò violerebbe la fiducia di un utente e influirebbe sulla durata della batteria dell’utente.
Le violazioni della promessa
userVisibleOnlycomporteranno la revoca di un abbonamento push.
(enfasi mia)
Questo è spiegato più in dettaglio nel video WWDC di Apple su Web Push, a 9:57
Notare che stiamo esplicitamente affermando che promettiamo di rendere sempre visibili all’utente i push. Mentre lo standard per l’API JavaScript Push accetta facoltativamente runtime JavaScript silenziosi in risposta a un push, la maggior parte dei browser non lo supporta. Safari non lo supporta.
… e poi a 13:35:
Come menzionato quando vi ho mostrato il codice su come richiedere un abbonamento push, dovete promettere che i push saranno visibili all’utente. La gestione di un evento push non è un invito per il vostro JavaScript a ottenere un runtime silenzioso in background. Farlo violerebbe sia la fiducia dell’utente che la durata della batteria dell’utente. Quando si gestisce un evento push, è effettivamente necessario pubblicare una notifica nel Centro Notifiche. Altri browser hanno contromisure contro la violazione della promessa di rendere i push visibili all’utente, e così anche Safari. Nella build beta di macOS Ventura, dopo tre eventi push in cui non si riesce a pubblicare una notifica in modo tempestivo, l’abbonamento push del tuo sito verrà revocato. Dovrai ripetere il flusso di autorizzazione.
(enfasi mia)
Apple consiglia di mostrare le notifiche immediatamente, non dopo la chiusura delle notifiche
Il codice consigliato da Apple è simile a questo, a 11:39:
self.addEventListener('push', (event) => {
let pushMessageJSON = event.data.json();
// Il nostro server inserisce tutto il necessario per mostrare la notifica
// nei nostri dati JSON.
event.waitUntil(self.registration.showNotification(pushMessageJSON.title, {
body: pushMessageJSON.body,
tag: pushMessageJSON.tag,
actions: [{
action: pushMessageJSON.actionURL,
title: pushMessageJSON.actionTitle,
}]
}));
}
Ricordate come, quando ci siamo abbonati ai push, il nostro JavaScript ha promesso che sarebbero sempre stati visibili all’utente? Ciò significa che dobbiamo sempre mostrare una notifica nativa della piattaforma in risposta a ogni push. È meglio farlo il prima possibile nel gestore dell’evento push.
Il codice di Discourse non segue la best practice raccomandata. Il codice di Discourse prima chiude tutte le notifiche e solo dopo mostra una notifica.
Discourse dovrebbe sempre chiamare showNotification in risposta a un evento push, e dovrebbe sempre farlo il prima possibile.