Notifications push sur le Web ouvert

Si vous demandez à des développeurs quelles fonctionnalités des appareils mobiles manquent 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 avec des contenus personnalisés et engageants.

À partir de la version 42 de Chrome, l'API Push et l'API Notification sont disponibles pour les développeurs.

L'API Push dans Chrome repose sur plusieurs technologies différentes, y compris les fichiers manifestes d'application Web et les service workers. Dans cet article, nous allons nous intéresser à chacune de ces technologies, mais seulement au strict minimum pour activer les messages push. Pour mieux comprendre certaines des autres fonctionnalités des fichiers manifestes et des fonctionnalités hors connexion des service workers, consultez les liens ci-dessus.

Nous examinerons également les fonctionnalités qui seront ajoutées à l'API dans les futures versions de Chrome, et enfin, nous publierons une FAQ.

Implémenter le message push pour Chrome

Cette section décrit chaque étape à effectuer pour prendre en charge les messages push dans votre application Web.

Enregistrer un service worker

L'implémentation des messages push pour le Web dépend d'un service worker. 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'aucune page ne soit ouverte, et envoyer un événement afin que vous puissiez décider comment gérer ce message push.

Vous trouverez ci-dessous un exemple illustrant comment enregistrer un service worker dans votre application Web. Une fois l'enregistrement terminé, nous appelons initialiseState(), que nous aborderons 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 clics sur les boutons abonne l'utilisateur ou le désabonne pour lui envoyer des messages. isPushEnabled est une variable globale qui vérifie 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 a la logique pour gérer 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 messagerie push activée et désactivée dans Chrome.

Une fois le service worker enregistré, nous devons configurer l'état de l'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 tenue à jour en cas de changement. En d'autres termes, s'ils activent les messages push pour votre site, quittent le site et y reviennent une semaine plus tard, votre interface utilisateur doit indiquer que les messages push sont déjà activés.

Vous trouverez quelques consignes relatives à l'expérience utilisateur dans ce document. 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érents points à prendre en compte et l'état du transfert 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 interface utilisateur, vous devez définir l'état initial sur "Désactivé". Cela permet également d'éviter 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 aperçu de ces étapes:

  • Nous vérifions que showNotification est disponible dans le prototype ServiceWorkerRegistration. Sans cela, nous ne serons pas en mesure d'afficher une notification de notre service worker lorsqu'un message push est reçu.
  • Nous vérifions la valeur actuelle de Notification.permission pour nous assurer qu'il ne s'agit pas de "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 les détails qui existent dans l'objet d'abonnement dans la suite de cet article.

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 les cas où l'utilisateur souhaite activer les messages push. Avant cela, 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 distribution des messages push. Toutefois, pour utiliser l'API FCM, vous devez configurer un projet dans la Firebase Developer Console.

Les étapes suivantes sont spécifiques à Chrome, Opera pour Android et le navigateur Samsung qu'ils utilisent FCM. Nous verrons dans la suite de 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 "Create New Project" (Créer un projet).

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

Ajoutez un nom de projet, puis créez-le. Vous êtes redirigé vers le 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 dans l'angle supérieur 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 le transfert 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 afin qu'ils puissent utiliser FCM / GCM.

Le paramètre gcm_sender_id est utilisé par ces navigateurs lorsqu'il abonne l'appareil d'un utilisateur avec FCM. Cela signifie que FCM peut identifier l'appareil de l'utilisateur, 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 d'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, vous obtiendrez une exception si vous tentez d'abonner l'utilisateur au transfert de messages, 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 retourner dans le code JavaScript de votre site.

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

Cela demandera à l'utilisateur d'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() est résolue, vous recevez un objet PushSubscription qui contient 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, bien que rien ne se produise tant que nous n'avons pas ajouté un écouteur d'événements push à notre fichier service worker.

Écouteur d'événements push de 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é à mettre en évidence dans cet exemple est la méthode event.waitUntil(). Cette méthode accepte une promesse et prolonge la durée de vie d'un gestionnaire d'événements (ou peut être considérée comme le maintien actif du service worker), 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 avons envoyé deux messages push au même point de terminaison, avec un court délai entre eux, et que nous affichons les 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 balise différente ou aucune balise. Nous examinerons un exemple plus complet d'affichage d'une notification plus loin dans 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 de 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

Le registration_id serait:

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

Cette règle est spécifique aux navigateurs utilisant FCM. Dans un navigateur standard, vous obtenez simplement un point de terminaison que vous appelez de manière standard, 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'enregistrement_id. Pour ce faire dans Python, vous pouvez:

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 disposez de l'ID d'enregistrement, vous pouvez appeler l'API FCM. Vous pouvez trouver 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 la valeur 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.
    • La clé API permet à FCM de trouver l'ID d'expéditeur approprié, de s'assurer que l'utilisateur a accordé l'autorisation pour votre projet et, enfin, de s'assurer que l'adresse IP du serveur figure sur la liste d'autorisation 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 données de formulaire.
  • Tableau de registration_ids : il s'agit des ID d'enregistrement que vous devez extraire des points de terminaison de vos utilisateurs.

Veuillez consulter la documentation sur l'envoi de messages push depuis votre serveur. Toutefois, pour un contrôle rapide de votre service worker, vous pouvez utiliser cURL afin d'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.

Vous devriez voir une bonne notification:

    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 de Chrome pour Android.

Lorsque vous développez votre logique de backend, n'oubliez pas que l'en-tête "Authorization" et le format du corps du POST sont spécifiques au point de terminaison FCM. Par conséquent, vous devez détecter à quel moment le point de terminaison est destiné à FCM et ajouter l'en-tête et mettre 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'un des inconvénients de l'implémentation actuelle de l'API Push dans Chrome est que vous ne pouvez pas envoyer de données avec un message push. Non, rien. En effet, dans une implémentation ultérieure, les données de 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 push, ne pourra pas facilement afficher le contenu du message push. Cela constitue également une protection contre d'autres failles, telles qu'une mauvaise validation des certificats HTTPS et des attaques MITM ("man in the middle") entre votre serveur et le fournisseur push. Cependant, ce chiffrement n'est pas encore pris en charge. En attendant, vous devez effectuer une extraction 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 et, en ce qui concerne les exemples, elle ne couvre pas un cas d'utilisation réel.

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 un élément spécifique, ou d'aller plus loin et de mettre en cache des pages ou des données. Ainsi, lorsque l'utilisateur clique sur la notification, tout est 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 récupérons des données à partir d'une API, nous convertissons la réponse en objet et nous l'utilisons pour remplir 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, une fois encore, de souligner que event.waitUntil() accepte une promesse qui se traduit par la promesse renvoyée par showNotification(), ce qui signifie que notre écouteur d'événements ne se fermera pas tant que l'appel fetch() asynchrone ne sera pas terminé et que la notification s'affichera.

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

Ouverture d'une URL lorsque l'utilisateur clique sur une notification

Lorsque l'utilisateur clique sur une notification, un événement notificationclick est envoyé à votre service worker. Dans votre gestionnaire, vous pouvez prendre les mesures appropriées, comme sélectionner 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 s'il existe et en ouvrant un nouvel onglet.

Un article détaille ce que vous pouvez faire avec l'API Notification.

Se désabonner de l'appareil d'un utilisateur

Vous vous êtes abonné à l'appareil d'un utilisateur et celui-ci reçoit des messages push, mais comment pouvez-vous le désabonner ?

Pour se désabonner de l'appareil d'un utilisateur, il faut principalement appeler la méthode unsubscribe() au niveau de 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). C'est exactement ce que fait le code ci-dessous:

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

Il est possible que les abonnements ne soient pas synchronisés entre FCM et votre serveur. Assurez-vous que votre serveur analyse le corps de la réponse du POST d'envoi de l'API FCM en recherchant les résultats error:NotRegistered et canonical_id, comme expliqué dans la documentation FCM.

Les abonnements peuvent également ne pas être synchronisés entre le service worker et votre serveur. Par exemple, une fois que vous vous êtes abonné ou désabonné, une connexion réseau irrégulière peut vous empêcher de mettre à jour votre serveur, ou un utilisateur peut révoquer l'autorisation de notification, 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" est accordée.

Dans sendSubscriptionToServer(), vous devrez réfléchir à la manière dont vous gérez les requêtes réseau ayant échoué lors de la mise à jour du endpoint. Une solution consiste à suivre l'état de endpoint dans un cookie pour déterminer si votre serveur a besoin des informations les plus récentes ou non.

Toutes les étapes ci-dessus permettent d'implémenter complètement la messagerie push sur le Web dans Chrome 46. Il existe toujours des fonctionnalités spécifiques 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 à vos applications Web dès aujourd'hui.

Déboguer votre application Web

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

Les bugs de la page peuvent être débogués à l'aide des 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 en dehors des service workers en cours d'exécution.
  2. Accédez à chrome://serviceworker-internals pour afficher l'état des service workers et voir les éventuelles erreurs. Cette page est temporaire jusqu'à ce que les outils de développement proposent 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 worker 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 où se trouve la case à cocher &quot;Mettre en pause 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 le résoudre, car vous ne pouvez pas savoir si Chrome a reçu quelque chose. La clé est que la réponse de FCM aboutit lorsque votre serveur effectue un appel d'API. Cela ressemblera à quelque chose comme:

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

Notez la réponse "success": 1. Si vous constatez un échec, cela signifie qu'il y a un problème avec l'ID d'enregistrement FCM et que le message push n'est pas envoyé à Chrome.

Déboguer les 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, trouver votre appareil et rechercher un élément de liste nommé "Worker pid:....", qui contient l'URL de votre service worker.

Capture d&#39;écran montrant où résident les service workers dans Chrome Inspect

Expérience utilisateur 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 extrêmes liés à l'utilisation de ces notifications.

L'avenir des messages push sur Chrome et sur 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 devez être en mesure de prendre le point de terminaison, de le transmettre à votre serveur et d'envoyer des messages push en mettant en œuvre le protocole Web Push.

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

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

L'objectif final de Chrome est d'adopter 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 formater les données de charge utile d'une manière spécifique et ajouter la clé d'autorisation.

Comment mettre en œuvre le protocole Web Push ?

Firefox Nightly travaille actuellement sur le mode Push et sera probablement le premier navigateur à mettre en œuvre 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 suis présente à la fois sur le Web et dans un format natif ?

Il n'existe pas de solution pour le moment, mais vous pouvez suivre la progression dans Chromium.

Le scénario idéal consisterait à avoir un type d'ID pour l'appareil d'un utilisateur, puis, côté serveur, à faire correspondre les ID d'abonnement à l'application native et à l'application Web, et à choisir celui auquel envoyer un message push. Pour ce faire, vous pouvez utiliser la taille de l'écran, le modèle d'appareil et le partage d'une clé générée entre l'application Web et l'application native, mais chaque approche a ses avantages et ses inconvénients.

Pourquoi ai-je besoin d'un gcm_sender_id ?

Cette étape 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 est finalisée et que FCM la prend en charge.

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

L'utilisation de messages push présente un avantage : même si votre page est fermée, votre service worker est activé et peut afficher une notification. La connexion des WebSockets et EventSource est fermée à la fermeture de la page ou du navigateur.

Que faire si je n'ai pas besoin d'envoyer des é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 le mode push sans afficher les notifications (par exemple, push silencieuse en arrière-plan) ?

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 requis ? 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 prend en charge sa version stable et Mozilla a été en cours d'élaboration dans Firefox Nightly. Pour en savoir plus, consultez le bug concernant l'implémentation de l'API Push. Vous pouvez suivre l'implémentation des notifications ici.

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

Ce n'est pas possible pour le moment, mais nous prévoyons de l'ajouter afin d'obtenir la liste des notifications actuellement visibles. Si vous souhaitez définir un délai d'expiration pour les notifications après leur affichage, nous aimerions en savoir plus. Ajoutez un commentaire et nous le transmettrons à l'équipe Chrome.

Si vous devez uniquement arrêter l'envoi d'une notification push à l'utilisateur après un certain temps et que la durée pendant laquelle la notification reste visible n'est pas importante, vous pouvez utiliser le paramètre Ttl (Time To Live) de FCM. En savoir plus

Quelles sont les limites des messages push dans Chrome ?

Quelques limites sont décrites dans cet article:

  • L'utilisation de CCM dans Chrome en tant que service push crée un certain nombre d'exigences propriétaires. Nous travaillons ensemble pour 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 pour ordinateur n'accepte pas les messages push si Chrome n'est pas en cours d'exécution. Cela diffère de ChromeOS et d'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. En savoir plus

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

Ce problème ne concerne 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 a reçu l'envoi ?

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 "Réduire_key" que vous pouvez utiliser pour indiquer à FCM de remplacer tout message en attente ayant la même clé "Réduire_key" par le nouveau message.

Pour en savoir plus, cliquez ici.