Les notifications iOS peuvent perdre la permission de pousser si l'utilisateur est actuellement actif

Les notifications iOS peuvent perdre la permission de pousser si la notification est supprimée. Le code de Discourse est configuré pour supprimer éventuellement les notifications, et perdra ainsi la permission de pousser lorsque cela se produira trois fois.

Voici le code du service worker de notification push.

Ce code contient un bug critique à la ligne 178. Le service worker vérifie si l’utilisateur est actif (c’est-à-dire non inactif). Dans ce cas, l’événement push renvoie false sans afficher de notification.

(Il vérifie également payload.hide_when_active, mais il s’avère que hide_when_active est toujours vrai, et donc ce code renvoie toujours false lorsque l’utilisateur est actif.)

Apple interdit les notifications silencieuses, révoquant la permission de notification après trois événements qui n’affichent pas de notifications

Ceci n’est pas acceptable selon les règles d’Apple pour les notifications push.

https://webkit.org/blog/12945/meet-web-push/

Puissance et confidentialité

Le projet open source WebKit et Apple traitent la confidentialité comme un droit humain fondamental. Comme pour d’autres fonctionnalités privilégiées de la plateforme web, la demande d’un abonnement push nécessite un geste explicite de l’utilisateur. Elle exige également que vous définissiez le drapeau userVisibleOnly sur true, et que vous remplissiez cette promesse en affichant toujours une notification en réponse à un message push.

L’API Web Push n’est pas une invitation à une exécution silencieuse en arrière-plan, car cela violerait la confiance d’un utilisateur et affecterait la durée de vie de la batterie de l’utilisateur.

Les violations de la promesse userVisibleOnly entraîneront la révocation d’un abonnement push.

(emphase ajoutée)

Ceci est expliqué plus en détail dans la vidéo WWDC d’Apple sur les Web Pushes, à 9:57

https://developer.apple.com/videos/play/wwdc2022/10098/?time=596

Notez que nous indiquons explicitement que nous promettons de toujours rendre les notifications visibles par l’utilisateur. Bien que la norme pour l’API JavaScript Push autorise éventuellement une exécution JavaScript silencieuse en réponse à une notification push, la plupart des navigateurs ne le prennent pas en charge. Safari ne le prend pas en charge.

… et ensuite à 13:35 :

https://developer.apple.com/videos/play/wwdc2022/10098/?time=814

Comme mentionné lorsque je vous ai montré le code pour demander un abonnement push, vous devez promettre que les notifications seront toujours visibles par l’utilisateur. La gestion d’un événement push n’est pas une invitation pour votre JavaScript à obtenir une exécution silencieuse en arrière-plan. Le faire violerait à la fois la confiance de l’utilisateur et la durée de vie de la batterie de l’utilisateur. Lors de la gestion d’un événement push, vous êtes en fait tenu d’afficher une notification dans le Centre de notifications. D’autres navigateurs ont des contre-mesures contre la violation de la promesse de rendre les notifications visibles par l’utilisateur, tout comme Safari. Dans la version bêta de macOS Ventura, après trois événements push où vous ne parvenez pas à afficher une notification en temps voulu, l’abonnement push de votre site sera révoqué. Vous devrez à nouveau passer par le flux de permission.

(emphase ajoutée)

Apple recommande d’afficher les notifications immédiatement, pas après la fermeture des notifications

Le code recommandé par Apple ressemble à ceci, à 11:39 :

https://developer.apple.com/videos/play/wwdc2022/10098/?time=699

self.addEventListener('push', (event) => {
    let pushMessageJSON = event.data.json();

    // Notre serveur met tout ce qui est nécessaire pour afficher la notification
    // dans nos données JSON.
    event.waitUntil(self.registration.showNotification(pushMessageJSON.title, {
        body: pushMessageJSON.body,
        tag: pushMessageJSON.tag,
        actions: [{
            action: pushMessageJSON.actionURL,
            title: pushMessageJSON.actionTitle,
        }]
    }));
}

Rappelez-vous comment, lorsque nous nous sommes abonnés aux notifications push, notre JavaScript a promis qu’elles seraient toujours visibles par l’utilisateur ? Cela signifie que nous devons toujours afficher une notification native de la plateforme en réponse à chaque notification push. Il est préférable de le faire le plus tôt possible dans votre gestionnaire d’événements push.

Le code de Discourse ne suit pas la meilleure pratique recommandée. Le code de Discourse ferme d’abord toutes les notifications, puis affiche une notification.

Discourse devrait toujours appeler showNotification en réponse à un événement push, et il devrait toujours le faire dès que possible.

8 « J'aime »

@Falco / @featheredtoast vos avis sur la question ?

Quel serait l’impact de la suppression de la vérification de fermeture et de la vérification d’inactivité ?

Dans l’ensemble, je ne suis pas du tout sûr de cette vérification d’inactivité, j’ai l’impression qu’elle ne fait qu’engendrer de la confusion.

Dans le pire des cas, si nous exigeons cela sur Android ou Desktop (hors Safari), nous pourrons toujours ajouter une condition ici, mais mon sentiment est que nous devrions simplement supprimer le code ici.

Excellent débogage @dfabulich :hugs:

3 « J'aime »

Je note qu’il est acceptable de faire la fermeture, je suppose, tant qu’elle est effectuée après avoir appelé showNotification.

… mais honnêtement, je ne vois pas l’intérêt de fermer les notifications. Autant les laisser s’accumuler dans le centre de notifications, à mon avis.

Note : Cette API ne doit pas être utilisée simplement pour que la notification soit supprimée de l’écran après un délai fixe, car cette méthode supprimera également la notification de tout centre de notifications, empêchant les utilisateurs d’interagir avec elle après qu’elle ait été initialement affichée. Une utilisation valide de cette API serait de supprimer une notification qui n’est plus pertinente (par exemple, l’utilisateur a déjà lu la notification sur la page Web dans le cas d’une application de messagerie ou la chanson suivante est déjà en cours de lecture dans une application musicale).

3 « J'aime »

D’après ce que j’ai lu sur ce sujet ce week-end, nous ne pouvons même pas utiliser async/promises dans le gestionnaire d’événements push, nous devons le montrer dès que possible, sinon Apple révoquera vos droits de notification.

Tout cela correspond à ce que dit @dfabulich.

Je pense que nous sommes trop “intelligents” pour notre propre bien, nous devrions en effet supprimer toutes les vérifications et simplement afficher la notification.

6 « J'aime »

Un grand merci à @dfabulich pour cette découverte !

3 « J'aime »

OK, j’ai une PR pour ça.

@Falco / @featheredtoast devons-nous la fusionner ?

Si nous devons ignorer les notifications push, nous devons le faire sur le serveur et non sur le client. La logique d’effondrement a toujours été quelque peu discutable, les applications n’ont pas tendance à le faire.

2 « J'aime »

Oh oui, il est beaucoup plus logique de ne pousser les notifications que lorsqu’elles doivent être affichées. Cela devrait éventuellement réduire les notifications excessives ailleurs, mais je suis d’accord pour fusionner cela ici :+1:

Concernant la réduction des notifications, c’est dommage de perdre cela, mais… idéalement, nous pourrions faire quelque chose de similaire à la fermeture automatique d’autres applications lorsqu’un utilisateur consulte ses notifications sur n’importe quel appareil connecté, mais cela pourrait nécessiter un peu de travail supplémentaire. L’intention est la même : ne jamais avoir une marée de notifications obsolètes qui s’accumulent. Encore une fois, ce n’est pas grave, mais nous devrons y revenir plus tard, en fonction de la gêne occasionnée.

2 « J'aime »