Notifications push sur le Web ouvert

Si vous demandez à un groupe de développeurs quelles fonctionnalités des appareils mobiles ne sont pas disponibles sur le Web, les notifications push sont toujours en haut de la liste.

Les notifications push permettent à vos utilisateurs de s'abonner aux mises à jour en temps réel des sites qu'ils apprécient et vous permettent de les réengager efficacement à l'aide de contenus personnalisés et engageants.

À partir de la version 42 de Chrome, les développeurs peuvent utiliser l'API Push et l'API Notification.

L'API Push de Chrome repose sur plusieurs technologies différentes, y compris les fichiers manifestes d'application Web et les service workers. Dans cet article, nous allons examiner chacune de ces technologies, mais uniquement le strict minimum pour mettre en place la messagerie push. Pour mieux comprendre certaines des autres fonctionnalités des fichiers manifestes et les fonctionnalités hors connexion des service workers, veuillez consulter les liens ci-dessus.

Nous verrons également ce qui sera ajouté à l'API dans les futures versions de Chrome, et nous terminerons par une FAQ.

Implémenter la messagerie push pour Chrome

Cette section décrit chaque étape à suivre pour prendre en charge la messagerie push dans votre application Web.

Enregistrer un service worker

Un service worker est nécessaire pour implémenter des messages push pour le Web. En effet, lorsqu'un message push est reçu, le navigateur peut démarrer un service worker, qui s'exécute en arrière-plan sans qu'une page soit ouverte, et distribuer un événement afin que vous puissiez décider de la manière de gérer ce message push.

Vous trouverez ci-dessous un exemple d'enregistrement d'un service worker dans votre application Web. Une fois l'enregistrement terminé, nous appelons initialiseState(), que nous verrons bientôt.

var isPushEnabled = false;



window.addEventListener('load', function() {
    var pushButton = document.querySelector('.js-push-button');
    pushButton.addEventListener('click', function() {
    if (isPushEnabled) {
        unsubscribe();
    } else {
        subscribe();
    }
    });

    // Check that service workers are supported, if so, progressively
    // enhance and add push messaging support, otherwise continue without it.
    if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js')
    .then(initialiseState);
    } else {
    console.warn('Service workers aren\'t supported in this browser.');
    }
});

Le gestionnaire de clic sur le bouton abonne ou désabonne l'utilisateur aux messages push. isPushEnabled est une variable globale qui suit simplement si les messages push sont actuellement abonnés ou non. Ceux-ci seront référencés dans les extraits de code.

Nous vérifions ensuite que les service workers sont compatibles avant d'enregistrer le fichier service-worker.js, qui contient la logique de gestion d'un message push. Ici, nous indiquons simplement au navigateur que ce fichier JavaScript est le service worker de notre site.

Configurer l'état initial

Exemple d'expérience utilisateur de la messagerie push activée et désactivée dans Chrome.

Une fois le service worker enregistré, nous devons configurer l'état de notre UI.

Les utilisateurs s'attendent à ce qu'une interface utilisateur simple permette d'activer ou de désactiver les messages push sur votre site, et qu'elle soit mise à jour en cas de changement. En d'autres termes, s'ils activent les messages push pour votre site, quittent la page et reviennent une semaine plus tard, votre UI doit indiquer que les messages push sont déjà activés.

Vous trouverez des consignes relatives à l'expérience utilisateur dans ce document. Dans cet article, nous allons nous concentrer sur les aspects techniques.

À ce stade, vous pensez peut-être qu'il n'y a que deux états à gérer : activé ou désactivé. Il existe toutefois d'autres états entourant les notifications dont vous devez tenir compte.

Schéma illustrant les différentes considérations et l'état de la méthode push dans Chrome

Nous devons vérifier un certain nombre d'API avant d'activer notre bouton. Si tout est compatible, nous pouvons activer notre UI et définir l'état initial pour indiquer si les messages push sont abonnés ou non.

Étant donné que la majorité de ces vérifications entraînent la désactivation de notre UI, vous devez définir l'état initial sur "Désactivé". Cela évite également toute confusion en cas de problème avec le code JavaScript de votre page, par exemple si le fichier JS ne peut pas être téléchargé ou si l'utilisateur a désactivé JavaScript.

<button class="js-push-button" disabled>
    Enable Push Messages
</button>

Avec cet état initial, nous pouvons effectuer les vérifications décrites ci-dessus dans la méthode initialiseState(), c'est-à-dire après l'enregistrement de notre service worker.

// Once the service worker is registered set the initial state
function initialiseState() {
    // Are Notifications supported in the service worker?
    if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
    console.warn('Notifications aren\'t supported.');
    return;
    }

    // Check the current Notification permission.
    // If its denied, it's a permanent block until the
    // user changes the permission
    if (Notification.permission === 'denied') {
    console.warn('The user has blocked notifications.');
    return;
    }

    // Check if push messaging is supported
    if (!('PushManager' in window)) {
    console.warn('Push messaging isn\'t supported.');
    return;
    }

    // We need the service worker registration to check for a subscription
    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    // Do we already have a push message subscription?
    serviceWorkerRegistration.pushManager.getSubscription()
        .then(function(subscription) {
        // Enable any UI which subscribes / unsubscribes from
        // push messages.
        var pushButton = document.querySelector('.js-push-button');
        pushButton.disabled = false;

        if (!subscription) {
            // We aren't subscribed to push, so set UI
            // to allow the user to enable push
            return;
        }

        // Keep your server in sync with the latest subscriptionId
        sendSubscriptionToServer(subscription);

        // Set your UI to show they have subscribed for
        // push messages
        pushButton.textContent = 'Disable Push Messages';
        isPushEnabled = true;
        })
        .catch(function(err) {
        console.warn('Error during getSubscription()', err);
        });
    });
}

Voici un bref aperçu de ces étapes :

  • Nous vérifions que showNotification est disponible dans le prototype ServiceWorkerRegistration. Sans cela, nous ne pourrons pas afficher une notification de notre service worker lorsqu'un message push sera reçu.
  • Nous vérifions la valeur actuelle de Notification.permission pour nous assurer qu'elle n'est pas "denied". Une autorisation refusée signifie que vous ne pouvez pas afficher de notifications tant que l'utilisateur n'a pas modifié manuellement l'autorisation dans le navigateur.
  • Pour vérifier si les messages push sont pris en charge, nous vérifions que PushManager est disponible dans l'objet window.
  • Enfin, nous avons utilisé pushManager.getSubscription() pour vérifier si nous disposons déjà d'un abonnement. Dans ce cas, nous envoyons les détails de l'abonnement à notre serveur pour nous assurer que nous disposons des bonnes informations, et nous définissons notre interface utilisateur pour indiquer que la messagerie push est déjà activée ou non. Nous verrons plus tard dans cet article les détails de l'objet d'abonnement.

Nous attendons que navigator.serviceWorker.ready soit résolu pour vérifier un abonnement et activer le bouton push, car ce n'est qu'une fois que le service worker est actif que vous pouvez vous abonner aux messages push.

L'étape suivante consiste à gérer le moment où l'utilisateur souhaite activer les messages push. Toutefois, avant de pouvoir le faire, nous devons configurer un projet Google Developer Console et ajouter des paramètres à notre fichier manifeste pour utiliser Firebase Cloud Messaging (FCM), anciennement connu sous le nom de Google Cloud Messaging (GCM).

Créer un projet dans la console de développement Firebase

Chrome utilise FCM pour gérer l'envoi et la diffusion de messages push. Toutefois, pour utiliser l'API FCM, vous devez configurer un projet dans la console de développement Firebase.

Les étapes suivantes sont spécifiques à Chrome, Opera pour Android et au navigateur Samsung, qui utilisent FCM. Nous verrons plus tard dans cet article comment cela fonctionne dans d'autres navigateurs.

Créer un projet de développeur Firebase

Pour commencer, vous devez créer un projet sur https://console.firebase.google.com/ en cliquant sur "Créer un projet".

Capture d&#39;écran du nouveau projet Firebase

Ajoutez un nom de projet, créez-le, puis accédez au tableau de bord du projet:

Page d&#39;accueil du projet Firebase

Dans ce tableau de bord, cliquez sur la roue dentée à côté du nom de votre projet en haut à gauche, puis sur "Paramètres du projet".

Menu des paramètres du projet Firebase

Sur la page des paramètres, cliquez sur l'onglet "Cloud Messaging".

Menu de messagerie cloud du projet Firebase

Cette page contient la clé API pour les messages push, que nous utiliserons plus tard, ainsi que l'ID de l'expéditeur que nous devons placer dans le fichier manifeste de l'application Web dans la section suivante.

Ajouter un fichier manifeste d'application Web

Pour les notifications push, nous devons ajouter un fichier manifeste avec un champ gcm_sender_id pour que l'abonnement push aboutisse. Ce paramètre n'est requis que par Chrome, Opera pour Android et le navigateur Samsung pour qu'ils puissent utiliser FCM / GCM.

Le gcm_sender_id est utilisé par ces navigateurs lorsqu'ils abonnent l'appareil d'un utilisateur à FCM. Cela signifie que FCM peut identifier l'appareil de l'utilisateur et s'assurer que votre ID d'expéditeur correspond à la clé API correspondante et que l'utilisateur a autorisé votre serveur à lui envoyer des messages push.

Voici un fichier manifeste super simple:

{
    "name": "Push Demo",
    "short_name": "Push Demo",
    "icons": [{
        "src": "images/icon-192x192.png",
        "sizes": "192x192",
        "type": "image/png"
        }],
    "start_url": "/index.html?homescreen=1",
    "display": "standalone",
    "gcm_sender_id": "<Your Sender ID Here>"
}

Vous devez définir la valeur gcm_sender_id sur l'ID de l'expéditeur de votre projet Firebase.

Une fois que vous avez enregistré votre fichier manifeste dans votre projet (le fichier manifeste.json est un bon nom), référencez-le à partir de votre code HTML avec la balise suivante dans l'en-tête de votre page.

<link rel="manifest" href="/manifest.json">

Si vous n'ajoutez pas de fichier manifeste Web avec ces paramètres, une exception s'affichera lorsque vous tenterez d'abonner l'utilisateur aux messages push, avec l'erreur "Registration failed - no sender id provided" ou "Registration failed - permission denied".

S'abonner aux messages push

Maintenant que vous avez configuré un fichier manifeste, vous pouvez revenir au code JavaScript de votre site.

Pour vous abonner, vous devez appeler la méthode subscribe() sur l'objet PushManager, auquel vous accédez via le ServiceWorkerRegistration.

L'utilisateur sera alors invité à autoriser votre origine à envoyer des notifications push. Sans cette autorisation, vous ne pourrez pas vous abonner.

Si la promesse renvoyée par la méthode subscribe() se résout, vous recevrez un objet PushSubscription contenant un point de terminaison.

Le point de terminaison doit être enregistré sur votre serveur pour chaque utilisateur, car vous en aurez besoin pour envoyer des messages push ultérieurement.

Le code suivant abonne l'utilisateur aux messages push:

function subscribe() {
    // Disable the button so it can't be changed while
    // we process the permission request
    var pushButton = document.querySelector('.js-push-button');
    pushButton.disabled = true;

    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    serviceWorkerRegistration.pushManager.subscribe()
        .then(function(subscription) {
        // The subscription was successful
        isPushEnabled = true;
        pushButton.textContent = 'Disable Push Messages';
        pushButton.disabled = false;

        // TODO: Send the subscription.endpoint to your server
        // and save it to send a push message at a later date
        return sendSubscriptionToServer(subscription);
        })
        .catch(function(e) {
        if (Notification.permission === 'denied') {
            // The user denied the notification permission which
            // means we failed to subscribe and the user will need
            // to manually change the notification permission to
            // subscribe to push messages
            console.warn('Permission for Notifications was denied');
            pushButton.disabled = true;
        } else {
            // A problem occurred with the subscription; common reasons
            // include network errors, and lacking gcm_sender_id and/or
            // gcm_user_visible_only in the manifest.
            console.error('Unable to subscribe to push.', e);
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
        }
        });
    });
}

À ce stade, votre application Web est prête à recevoir un message push, mais rien ne se passe tant que nous n'avons pas ajouté un écouteur d'événements push à notre fichier de service worker.

Écouteur d'événements de transfert de données Service Worker

Lorsqu'un message push est reçu (nous verrons comment l'envoyer dans la section suivante), un événement push est envoyé dans votre service worker. À ce stade, vous devez afficher une notification.

self.addEventListener('push', function(event) {
    console.log('Received a push message', event);

    var title = 'Yay a message.';
    var body = 'We have received a push message.';
    var icon = '/images/icon-192x192.png';
    var tag = 'simple-push-demo-notification-tag';

    event.waitUntil(
    self.registration.showNotification(title, {
        body: body,
        icon: icon,
        tag: tag
    })
    );
});

Ce code enregistre un écouteur d'événements push et affiche une notification avec un titre, un corps de texte, une icône et une balise de notification prédéfinis. Une subtilité à souligner avec cet exemple est la méthode event.waitUntil(). Cette méthode reçoit une promesse et prolonge la durée de vie d'un gestionnaire d'événements (ou peut être considérée comme un moyen de maintenir le worker de service actif), jusqu'à ce que la promesse soit réglée. Dans ce cas, la promesse transmise à event.waitUntil est la promesse renvoyée par showNotification().

La balise de notification sert d'identifiant pour les notifications uniques. Si nous envoyons deux messages push au même point de terminaison, avec un court délai entre eux, et que nous affichons des notifications avec la même balise, le navigateur affiche la première notification et la remplace par la seconde lorsque le message push est reçu.

Si vous souhaitez afficher plusieurs notifications à la fois, utilisez une autre balise ou aucune balise du tout. Nous examinerons un exemple plus complet d'affichage d'une notification dans la suite de cet article. Pour l'instant, restons simples et voyons si l'envoi d'un message push affiche cette notification.

Envoyer un message push

Nous nous sommes abonné aux messages push et notre service worker est prêt à afficher une notification. Il est donc temps d'envoyer un message push via FCM.

Cela ne s'applique qu'aux navigateurs utilisant FCM.

Lorsque vous envoyez la variable PushSubscription.endpoint à votre serveur, le point de terminaison pour FCM est spécial. Un paramètre (registration_id) se trouve à la fin de l'URL.

Voici un exemple de point de terminaison:

https://fcm.googleapis.com/fcm/send/APA91bHPffi8zclbIBDcToXN_LEpT6iA87pgR-J-MuuVVycM0SmptG-rXdCPKTM5pvKiHk2Ts-ukL1KV8exGOnurOAKdbvH9jcvg8h2gSi-zZJyToiiydjAJW6Fa9mE3_7vsNIgzF28KGspVmLUpMgYLBd1rxaVh-L4NDzD7HyTkhFOfwWiyVdKh__rEt15W9n2o6cZ8nxrP

L'URL FCM est la suivante:

https://fcm.googleapis.com/fcm/send

La registration_id serait la suivante:

APA91bHPffi8zclbIBDcToXN_LEpT6iA87pgR-J-MuuVVycM0SmptG-rXdCPKTM5pvKiHk2Ts-ukL1KV8exGOnurOAKdbvH9jcvg8h2gSi-zZJyToiiydjAJW6Fa9mE3_7vsNIgzF28KGspVmLUpMgYLBd1rxaVh-L4NDzD7HyTkhFOfwWiyVdKh__rEt15W9n2o6cZ8nxrP

Cette particularité est propre aux navigateurs qui utilisent FCM. Dans un navigateur normal, vous obtiendriez simplement un point de terminaison et vous l'appelleriez de manière standard. Il fonctionnerait, quelle que soit l'URL.

Cela signifie que sur votre serveur, vous devez vérifier si le point de terminaison est destiné à FCM et, le cas échéant, extraire l'ID d'enregistrement. Pour ce faire en Python, vous pouvez procéder comme suit:

if endpoint.startswith('https://fcm.googleapis.com/fcm/send'):
    endpointParts = endpoint.split('/')
    registrationId = endpointParts[len(endpointParts) - 1]

    endpoint = 'https://fcm.googleapis.com/fcm/send'

Une fois que vous avez obtenu l'ID d'enregistrement, vous pouvez appeler l'API FCM. Vous trouverez la documentation de référence sur l'API FCM ici.

Voici les principaux aspects à prendre en compte lorsque vous appelez FCM:

  • Un en-tête Authorization avec une valeur de key=&lt;YOUR_API_KEY&gt; doit être défini lorsque vous appelez l'API, où &lt;YOUR_API_KEY&gt; est la clé API du projet Firebase.
    • FCM utilise la clé API pour trouver l'ID d'expéditeur approprié, s'assurer que l'utilisateur a autorisé votre projet et, enfin, s'assurer que l'adresse IP du serveur est autorisée pour ce projet.
  • Un en-tête Content-Type approprié de application/json ou application/x-www-form-urlencoded;charset=UTF-8, selon que vous envoyez les données au format JSON ou au format de formulaire.
  • Tableau de registration_ids : il s'agit des ID d'enregistrement que vous extrayez des points de terminaison de vos utilisateurs.

Veuillez consulter la documentation sur l'envoi de messages push depuis votre serveur. Toutefois, pour vérifier rapidement votre service worker, vous pouvez utiliser cURL pour envoyer un message push à votre navigateur.

Remplacez les valeurs &lt;YOUR_API_KEY&gt; et &lt;YOUR_REGISTRATION_ID&gt; de cette commande cURL par la vôtre, puis exécutez-la à partir d'un terminal.

Une notification devrait s'afficher:

    curl --header "Authorization: key=<YOUR_API_KEY>" --header
    "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d
    "{\"registration_ids\":[\"<YOUR_REGISTRATION_ID>\"]}"
Exemple de message push envoyé par Chrome pour Android.

Lorsque vous développez votre logique backend, n'oubliez pas que l'en-tête d'autorisation et le format du corps POST sont spécifiques au point de terminaison FCM. Détectez donc quand le point de terminaison est destiné à FCM, puis ajoutez l'en-tête et mettez en forme le corps POST de manière conditionnelle. Pour les autres navigateurs (et, espérons-le, Chrome à l'avenir), vous devrez mettre en œuvre le protocole Web Push.

L'implémentation actuelle de l'API Push dans Chrome présente un inconvénient : vous ne pouvez pas envoyer de données avec un message push. Non, rien. En effet, dans une future implémentation, les données de la charge utile devront être chiffrées sur votre serveur avant d'être envoyées à un point de terminaison de messagerie push. De cette façon, le point de terminaison, quel que soit le fournisseur de push, ne pourra pas facilement afficher le contenu du message push. Cela protège également contre d'autres failles, telles qu'une mauvaise validation des certificats HTTPS et les attaques MITM entre votre serveur et le fournisseur de push. Toutefois, ce chiffrement n'est pas encore pris en charge. En attendant, vous devez effectuer une récupération pour obtenir les informations nécessaires pour renseigner une notification.

Exemple d'événement push plus complet

La notification que nous avons vue jusqu'à présent est assez basique. En ce qui concerne les exemples, elle ne couvre pas vraiment un cas d'utilisation concret.

En réalité, la plupart des utilisateurs voudront obtenir certaines informations de leur serveur avant d'afficher la notification. Il peut s'agir de données permettant de renseigner le titre et le message de la notification avec quelque chose de spécifique, ou d'aller plus loin et de mettre en cache certaines pages ou données afin que, lorsque l'utilisateur clique sur la notification, tout soit immédiatement disponible lorsque le navigateur est ouvert, même si le réseau n'est pas disponible à ce moment-là.

Dans le code suivant, nous extrayons des données à partir d'une API, convertissons la réponse en objet et l'utilisons pour renseigner notre notification.

self.addEventListener('push', function(event) {
    // Since there is no payload data with the first version
    // of push messages, we'll grab some data from
    // an API and use it to populate a notification
    event.waitUntil(
    fetch(SOME_API_ENDPOINT).then(function(response) {
        if (response.status !== 200) {
        // Either show a message to the user explaining the error
        // or enter a generic message and handle the
        // onnotificationclick event to direct the user to a web page
        console.log('Looks like there was a problem. Status Code: ' + response.status);
        throw new Error();
        }

        // Examine the text in the response
        return response.json().then(function(data) {
        if (data.error || !data.notification) {
            console.error('The API returned an error.', data.error);
            throw new Error();
        }

        var title = data.notification.title;
        var message = data.notification.message;
        var icon = data.notification.icon;
        var notificationTag = data.notification.tag;

        return self.registration.showNotification(title, {
            body: message,
            icon: icon,
            tag: notificationTag
        });
        });
    }).catch(function(err) {
        console.error('Unable to retrieve data', err);

        var title = 'An error occurred';
        var message = 'We were unable to get the information for this push message';
        var icon = URL_TO_DEFAULT_ICON;
        var notificationTag = 'notification-error';
        return self.registration.showNotification(title, {
            body: message,
            icon: icon,
            tag: notificationTag
        });
    })
    );
});

Il est utile de souligner une fois de plus que event.waitUntil() prend une promesse, ce qui entraîne la promesse renvoyée par showNotification(), ce qui signifie que notre écouteur d'événements ne se terminera pas tant que l'appel fetch() asynchrone n'est pas terminé et que la notification n'est pas affichée.

Vous remarquerez que nous affichons une notification même en cas d'erreur. En effet, si nous ne le faisons pas, Chrome affichera sa propre notification générique.

Ouvrir une URL lorsque l'utilisateur clique sur une notification

Lorsque l'utilisateur clique sur une notification, un événement notificationclick est distribué dans votre service worker. Dans votre gestionnaire, vous pouvez prendre les mesures appropriées, comme mettre en surbrillance un onglet ou ouvrir une fenêtre avec une URL spécifique :

self.addEventListener('notificationclick', function(event) {
    console.log('On notification click: ', event.notification.tag);
    // Android doesn't close the notification when you click on it
    // See: http://crbug.com/463146
    event.notification.close();

    // This looks to see if the current is already open and
    // focuses if it is
    event.waitUntil(
    clients.matchAll({
        type: "window"
    })
    .then(function(clientList) {
        for (var i = 0; i < clientList.length; i++) {
        var client = clientList[i];
        if (client.url == '/' && 'focus' in client)
            return client.focus();
        }
        if (clients.openWindow) {
        return clients.openWindow('/');
        }
    })
    );
});

Cet exemple ouvre le navigateur à la racine de l'origine du site, en sélectionnant un onglet de même origine existant, le cas échéant, et en ouvrant un nouvel onglet sinon.

Vous trouverez un article expliquant certaines des opérations que vous pouvez effectuer avec l'API Notification.

Désabonner l'appareil d'un utilisateur

Vous avez abonné l'appareil d'un utilisateur et il reçoit des messages push. Comment le désabonner ?

La procédure principale pour désabonner l'appareil d'un utilisateur consiste à appeler la méthode unsubscribe() sur l'objet PushSubscription et à supprimer le point de terminaison de vos serveurs (afin d'éviter d'envoyer des messages push dont vous savez qu'ils ne seront pas reçus). Le code ci-dessous fait exactement cela :

function unsubscribe() {
    var pushButton = document.querySelector('.js-push-button');
    pushButton.disabled = true;

    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    // To unsubscribe from push messaging, you need get the
    // subscription object, which you can call unsubscribe() on.
    serviceWorkerRegistration.pushManager.getSubscription().then(
        function(pushSubscription) {
        // Check we have a subscription to unsubscribe
        if (!pushSubscription) {
            // No subscription object, so set the state
            // to allow the user to subscribe to push
            isPushEnabled = false;
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
            return;
        }

        var subscriptionId = pushSubscription.subscriptionId;
        // TODO: Make a request to your server to remove
        // the subscriptionId from your data store so you
        // don't attempt to send them push messages anymore

        // We have a subscription, so call unsubscribe on it
        pushSubscription.unsubscribe().then(function(successful) {
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
            isPushEnabled = false;
        }).catch(function(e) {
            // We failed to unsubscribe, this can lead to
            // an unusual state, so may be best to remove
            // the users data from your data store and
            // inform the user that you have done so

            console.log('Unsubscription error: ', e);
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
        });
        }).catch(function(e) {
        console.error('Error thrown while unsubscribing from push messaging.', e);
        });
    });
}

Maintenir l'abonnement à jour

Les abonnements peuvent être désynchronisés entre FCM et votre serveur. Assurez-vous que votre serveur analyse le corps de la réponse de l'envoi POST de l'API FCM, à la recherche des résultats error:NotRegistered et canonical_id, comme expliqué dans la documentation FCM.

Les abonnements peuvent également être désynchronisés entre le service worker et votre serveur. Par exemple, après l'abonnement/le désabonnement, une connexion réseau instable peut vous empêcher de mettre à jour votre serveur. Un utilisateur peut également révoquer l'autorisation de recevoir des notifications, ce qui déclenche un désabonnement automatique. Gérez de tels cas en vérifiant régulièrement le résultat de serviceWorkerRegistration.pushManager.getSubscription() (par exemple, lors du chargement de la page) et en le synchronisant avec le serveur. Vous pouvez également vous réabonner automatiquement si vous n'avez plus d'abonnement et que Notification.permission == "granted".

Dans sendSubscriptionToServer(), vous devez déterminer comment gérer les requêtes réseau ayant échoué lors de la mise à jour de endpoint. Une solution consiste à suivre l'état de endpoint dans un cookie pour déterminer si votre serveur a besoin des derniers détails ou non.

Toutes les étapes ci-dessus permettent d'implémenter complètement la messagerie push sur le Web dans Chrome 46. Il existe encore des fonctionnalités spécifiées qui faciliteront les choses (comme une API standard pour déclencher des messages push), mais cette version vous permet de commencer à intégrer des messages push dans vos applications Web dès aujourd'hui.

Déboguer votre application Web

Lors de l'implémentation de messages push, les bugs se trouvent dans l'un des deux emplacements suivants: votre page ou votre service worker.

Les bugs de la page peuvent être débogués à l'aide de DevTools. Pour déboguer les problèmes de service worker, deux options s'offrent à vous:

  1. Accédez à chrome://inspect > Service workers. Cette vue ne fournit pas beaucoup d'informations, à l'exception des services workers en cours d'exécution.
  2. Accédez à chrome://serviceworker-internals. Vous pouvez y consulter l'état des services workers et les erreurs, le cas échéant. Cette page est temporaire jusqu'à ce que DevTools dispose d'un ensemble de fonctionnalités similaire.

L'un des meilleurs conseils que je puisse donner aux personnes qui débutent avec les service workers est d'utiliser la case à cocher "Ouvrir la fenêtre des outils de développement et suspendre l'exécution de JavaScript au démarrage du service workers pour le débogage". Cette case à cocher ajoute un point d'arrêt au début de votre service worker et met en pause l'exécution. Cela vous permet de reprendre ou de parcourir le script de service worker, et de voir si vous rencontrez des problèmes.

Capture d&#39;écran montrant l&#39;emplacement de la case à cocher &quot;Suspendre l&#39;exécution&quot; sur serviceworker-internals.

S'il semble y avoir un problème entre FCM et l'événement push de votre service worker, vous ne pouvez pas faire grand-chose pour déboguer le problème, car vous ne pouvez pas savoir si Chrome a reçu quoi que ce soit. La clé est que la réponse de FCM aboutit lorsque votre serveur effectue un appel d'API. Cela ressemblera à peu près à ceci:

{"multicast_id":1234567890,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1234567890"}]}

Notez la réponse "success": 1. Si un échec s'affiche à la place, cela suggère que quelque chose ne va pas avec l'ID d'enregistrement FCM et que le message push n'est pas envoyé à Chrome.

Déboguer des service workers dans Chrome pour Android

Pour le moment, le débogage des service workers sur Chrome pour Android n'est pas évident. Vous devez accéder à chrome://inspect, rechercher votre appareil, puis un élément de liste intitulé "Worker pid:....", qui contient l'URL de votre worker de service.

Capture d&#39;écran montrant l&#39;emplacement des services workers dans l&#39;outil d&#39;inspection Chrome

UX pour les notifications push

L'équipe Chrome a rédigé un document sur les bonnes pratiques en matière d'expérience utilisateur pour les notifications push, ainsi qu'un document couvrant certains des cas limites de fonctionnement des notifications push.

Avenir de la messagerie push sur Chrome et le Web ouvert

Cette section décrit en détail certaines des parties spécifiques à Chrome de cette implémentation que vous devez connaître et explique en quoi elles diffèrent des autres implémentations de navigateur.

Protocole Web push et points de terminaison

L'avantage de la norme de l'API Push est que vous devriez pouvoir prendre le point de terminaison, le transmettre à votre serveur et envoyer des messages push en implémentant le protocole Web Push.

Le protocole Web Push est une nouvelle norme que les fournisseurs de notifications push peuvent implémenter, ce qui permet aux développeurs de ne pas avoir à se soucier de l'identité du fournisseur de notifications push. L'idée est d'éviter d'avoir à s'inscrire pour des clés API et d'envoyer des données au format spécial, comme vous devez le faire avec FCM.

Chrome a été le premier navigateur à implémenter l'API Push. FCM n'est pas compatible avec le protocole Web Push. C'est pourquoi Chrome nécessite gcm_sender_id et que vous devez utiliser l'API REST pour FCM.

L'objectif final de Chrome est d'utiliser le protocole Web Push avec Chrome et FCM.

En attendant, vous devez détecter le point de terminaison "https://fcm.googleapis.com/fcm/send" et le gérer séparément des autres points de terminaison, c'est-à-dire mettre en forme les données de la charge utile de manière spécifique et ajouter la clé d'autorisation.

Comment implémenter le protocole Web Push ?

Firefox Nightly travaille actuellement sur le push et sera probablement le premier navigateur à implémenter le protocole Web Push.

Questions fréquentes

Où sont les caractéristiques ?

https://slightlyoff.github.io/ServiceWorker/spec/service_worker/ https://w3c.github.io/push-api/ https://notifications.spec.whatwg.org/

Puis-je éviter les notifications en double si ma présence sur le Web a plusieurs origines ou si je dispose à la fois d'une présence Web et d'une présence native ?

Il n'existe actuellement aucune solution à ce problème, mais vous pouvez suivre la progression sur Chromium.

Dans l'idéal, vous devriez disposer d'un type d'ID pour l'appareil d'un utilisateur, puis, côté serveur, faire correspondre les ID d'abonnement de l'application native et de l'application Web, puis décider à qui envoyer un message push. Vous pouvez le faire via la taille de l'écran, le modèle de l'appareil, le partage d'une clé générée entre l'application Web et l'application native, mais chaque approche présente des avantages et des inconvénients.

Pourquoi ai-je besoin d'un gcm_sender_id ?

Cette opération est nécessaire pour que Chrome, Opera pour Android et le navigateur Samsung puissent utiliser l'API Firebase Cloud Messaging (FCM). L'objectif est d'utiliser le protocole Web Push lorsque la norme sera finalisée et que FCM pourra le prendre en charge.

Pourquoi ne pas utiliser les Web Sockets ou les événements envoyés par le serveur (EventSource) ?

L'avantage d'utiliser des messages push est que, même si votre page est fermée, votre service worker sera réveillé et pourra afficher une notification. La connexion WebSockets et EventSource est fermée lorsque la page ou le navigateur est fermé.

Que faire si je n'ai pas besoin de la diffusion d'événements en arrière-plan ?

Si vous n'avez pas besoin de la diffusion en arrière-plan, les WebSockets constituent une excellente option.

Quand puis-je utiliser les notifications push sans afficher de notifications (push en arrière-plan silencieux) ?

Nous n'avons pas encore défini de date de disponibilité pour cette fonctionnalité, mais nous avons l'intention d'implémenter la synchronisation en arrière-plan. Bien que cela ne soit ni décidé, ni spécifié, nous envisageons d'activer le transfert silencieux avec la synchronisation en arrière-plan.

Pourquoi le protocole HTTPS est-il nécessaire ? Comment contourner ce problème pendant le développement ?

Les service workers requièrent des origines sécurisées pour s'assurer que leur script provient de l'origine prévue et ne provient pas d'une attaque MITM ("man in the middle"). Actuellement, cela signifie utiliser HTTPS sur les sites en ligne, bien que localhost fonctionne pendant le développement.

Comment fonctionne la compatibilité avec les navigateurs ?

Chrome est compatible avec la version stable, et Mozilla travaille sur la fonctionnalité de transfert dans Firefox Nightly. Pour en savoir plus, consultez le bug implémentation de l'API Push. Vous pouvez également suivre l'implémentation de la notification ici.

Puis-je supprimer une notification passé un certain délai ?

Pour le moment, ce n'est pas possible, mais nous prévoyons de proposer une liste des notifications actuellement visibles. Si vous avez un cas d'utilisation pour définir une date d'expiration pour la notification une fois qu'elle a été créée, nous aimerions en savoir plus. Veuillez ajouter un commentaire et nous le transmettrons à l'équipe Chrome.

Si vous souhaitez simplement empêcher l'envoi d'une notification push à l'utilisateur après un certain temps et que vous ne vous souciez pas de la durée de visibilité de la notification, vous pouvez utiliser le paramètre de durée de vie (TTL) de FCM. En savoir plus

Quelles sont les limites des messages push dans Chrome ?

Certaines limites sont décrites dans cet article:

  • L'utilisation de CCM par Chrome en tant que service push crée un certain nombre d'exigences propriétaires. Nous cherchons à déterminer si certaines de ces améliorations peuvent être supprimées à l'avenir.
  • Vous devez afficher une notification lorsque vous recevez un message push.
  • Chrome sur ordinateur présente l'inconvénient que si Chrome n'est pas en cours d'exécution, les messages push ne sont pas reçus. Ce n'est pas le cas avec ChromeOS et Android, où les messages push sont toujours reçus.

Ne devrions-nous pas utiliser l'API Permissions ?

L'API Permission est implémentée dans Chrome, mais elle n'est pas nécessairement disponible dans tous les navigateurs. Pour en savoir plus, consultez cette page.

Pourquoi Chrome n'ouvre-t-il pas l'onglet précédent lorsque je clique sur une notification ?

Ce problème n'affecte que les pages qui ne sont actuellement pas contrôlées par un service worker. Pour en savoir plus, consultez cet article du blog.

Que se passe-t-il si une notification est obsolète au moment où l'appareil de l'utilisateur reçoit le push ?

Vous devez toujours afficher une notification lorsque vous recevez un message push. Si vous souhaitez envoyer une notification, mais qu'elle n'est utile que pendant un certain temps, vous pouvez utiliser le paramètre "time_to_live" dans CCM afin que FCM n'envoie pas le message push s'il dépasse le délai d'expiration.

Pour en savoir plus, cliquez ici.

Que se passe-t-il si j'envoie 10 messages Push, mais que je souhaite que l'appareil n'en reçoive qu'un ?

FCM dispose d'un paramètre "collapse_key" que vous pouvez utiliser pour demander à FCM de remplacer tout message en attente ayant la même "collapse_key" par le nouveau message.

Pour en savoir plus, cliquez ici.