Notifications push sur le Web ouvert

Matt Gaunt

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 à des informations ponctuelles de sites qu'ils aiment et vous permettent de les renouer avec un contenu personnalisé et attrayant.

Depuis la version 42 de Chrome, l'API Push et l'API Notification sont accessibles aux développeurs.

L'API Push dans Chrome repose sur différents éléments technologiques, parmi lesquels les fichiers manifestes d'application Web et les service workers. Dans cet article, nous nous intéresserons à chacune de ces technologies, mais seulement au minimum nécessaire pour activer la messagerie push. Pour en savoir plus sur les autres fonctionnalités des fichiers manifestes et sur les fonctionnalités hors connexion des service workers, consultez les liens ci-dessus.

Nous étudierons également les éléments qui seront ajoutés à l'API dans les futures versions de Chrome, et pour finir, nous publierons des questions fréquentes.

Implémenter un message push pour Chrome

Cette section décrit chaque étape à effectuer pour pouvoir envoyer des messages 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'aucune page ne soit ouverte, puis envoyer un événement pour que vous puissiez décider comment 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 aborderons dans un instant.

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 ou désabonne l'utilisateur aux messages push. isPushEnabled est une variable globale qui vérifie simplement si les messages push sont actuellement abonnés ou non. Elles seront référencées dans les extraits de code.

Nous vérifions ensuite que les service workers sont compatibles avant d'enregistrer le fichier service-worker.js, qui dispose de la logique de traitement 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'activation et de désactivation des messages push dans Chrome.

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

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

Vous trouverez quelques consignes relatives à l'expérience utilisateur dans ce document. Dans cet article, nous nous concentrons 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 cependant d'autres états concernant les notifications dont vous devez prendre en compte.

Schéma mettant en évidence les différentes considérations 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 l'utilisateur est abonné ou non aux messages push.

É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 JavaScript 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 une fois que notre service worker est enregistré.

// 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 une brève présentation 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 quelle est la Notification.permission actuelle 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 ou non. Dans ce cas, nous envoyons les détails de l'abonnement à notre serveur pour vérifier que nous disposons des bonnes informations et configurons notre UI pour indiquer que la messagerie push est déjà activée ou non. Nous examinerons les détails disponibles dans l'objet "abonnement" plus loin dans cet article.

Nous attendons que navigator.serviceWorker.ready soit résolu pour rechercher 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. Avant cela, nous devons configurer un projet Google Developers Console et ajouter certains paramètres à notre fichier manifeste pour utiliser Firebase Cloud Messaging (FCM), anciennement Google Cloud Messaging (GCM).

Créer un projet dans la console pour les développeurs 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 concernent Chrome, Opera pour Android et le navigateur Samsung, et utilisent FCM. Nous verrons le fonctionnement de cette fonctionnalité dans d'autres navigateurs dans la suite de cet article.

Créer un projet de développement 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

Attribuez un nom au projet et créez-le. Vous êtes alors redirigé vers son tableau de bord:

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 du projet Firebase Cloud Messaging

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

Ajouter un fichier manifeste d'application Web

Pour la transmission 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 pouvoir 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.

Vous trouverez ci-dessous 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é le fichier manifeste dans votre projet (le fichier manifeste.json est un bon nom), référencez-le à partir de votre code HTML en ajoutant la balise suivante dans l'en-tête de la page.

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

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

S'abonner à la messagerie push

Maintenant que votre fichier manifeste est configuré, 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.

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 recevez un objet PushSubscription qui contiendra 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 passera tant que nous n'aurons 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é par votre service worker, et vous devez alors 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 comprend une promesse et prolonge la durée de vie d'un gestionnaire d'événements (ou peut être considérée comme le maintien de l'état de fonctionnement du service worker) jusqu'à ce que la promesse soit définie. Dans ce cas, la promesse transmise à event.waitUntil est la promesse renvoyée par showNotification().

La balise de notification agit comme un 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 le même tag, le navigateur affiche la première notification et la remplace par la seconde à la réception du message push.

Si vous souhaitez afficher plusieurs notifications à la fois, utilisez une autre balise ou n'utilisez 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és 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. À la fin de l'URL, il comporte un paramètre registration_id.

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

Ceci est spécifique aux navigateurs qui utilisent FCM. Dans un navigateur standard, il vous suffit d'obtenir un point de terminaison que vous appelez de manière standard. Il fonctionne quelle que soit l'URL.

Autrement dit, sur votre serveur, vous devez vérifier si le point de terminaison est bien adapté à FCM et, le cas échéant, extraire l'ID d'enregistrement. Pour ce faire dans Python, vous pouvez faire quelque chose comme:

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 en possession de l'ID d'enregistrement, vous pouvez appeler l'API FCM. Vous trouverez de 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 donné l'autorisation d'accéder à votre projet et, enfin, de s'assurer que l'adresse IP du serveur est ajoutée à 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 au format de formulaire.
  • Tableau de registration_ids : ID d'enregistrement que vous extrayez des points de terminaison de vos utilisateurs.

Veuillez consulter la documentation sur l'envoi de messages push à partir de votre serveur. Toutefois, pour un contrôle rapide de votre service worker, vous pouvez utiliser cURL pour envoyer un message push à votre navigateur.

Remplacez &lt;YOUR_API_KEY&gt; et &lt;YOUR_REGISTRATION_ID&gt; dans cette commande cURL par les vôtres et exécutez-la à partir d'un terminal.

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

Lors du développement de la logique de votre 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. Par conséquent, détectez si 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 nous espérons qu'il s'agira de 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 prochaine implémentation, 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 protège également contre d'autres failles telles que la mauvaise validation des certificats HTTPS et les attaques MITM ("man in the middle") entre votre serveur et le fournisseur push. Cependant, ce chiffrement n'est pas encore compatible. En attendant, vous devez effectuer une extraction pour obtenir les informations nécessaires afin de 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 suffisamment 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, 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 disponible immédiatement à l'ouverture du navigateur, même si le réseau n'est pas disponible à ce moment-là.

Dans le code suivant, nous récupérons certaines données d'une API, convertissons la réponse en objet et 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
        });
    })
    );
});

Une fois encore, il est utile de souligner que event.waitUntil() accepte une promesse qui se traduit par la promesse renvoyée par showNotification(). Cela signifie que notre écouteur d'événements ne se ferme pas tant que l'appel fetch() asynchrone n'est pas terminé et que la notification est affichée.

Vous remarquerez que nous affichons une notification même en cas d'erreur. En effet, si ce n'est pas le cas, 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 envoyé à votre service worker. Dans votre gestionnaire, vous pouvez prendre les mesures appropriées, par exemple 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, le cas échéant, et en ouvrant un nouveau.

Vous trouverez sur cette page un article consacré à certaines des actions que vous pouvez effectuer avec l'API Notification.

Désabonner un appareil d'un utilisateur

Vous avez abonné l'appareil d'un utilisateur et celui-ci reçoit des messages push. Comment pouvez-vous le désabonner ?

Pour désabonner l'appareil d'un utilisateur, les principaux éléments requis sont d'appeler la méthode unsubscribe() sur l'objet PushSubscription et de supprimer le point de terminaison de vos serveurs (afin de ne pas envoyer de 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 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 présenter une désynchronisation entre le service worker et votre serveur. Par exemple, après un abonnement ou un désabonnement réussi, 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 notifications, ce qui déclenche un désabonnement automatique. Pour gérer ces cas de figure, vérifiez régulièrement le résultat de serviceWorkerRegistration.pushManager.getSubscription() (par exemple, lors du chargement de la page) et synchronisez-le 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 prendre en compte la manière dont vous gérez 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 informations les plus récentes ou non.

Toutes les étapes ci-dessus entraînent une implémentation complète des messages 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 les messages push), mais cette version vous permet de commencer à créer des messages push dès aujourd'hui dans vos applications Web.

Déboguer votre application Web

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

Vous pouvez déboguer les bugs sur la page à l'aide des DevTools. Pour déboguer les problèmes liés aux service workers, vous avez deux options:

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

L'un des meilleurs conseils que je puisse donner à toute personne qui débute avec les service workers est d'utiliser la case à cocher intitulée "Open DevTools window and pause JavaScript execution on service worker startup for debug". Cette case à cocher permet d'ajouter un point d'arrêt au démarrage du service worker et de suspendre l'exécution. Cela vous permet de reprendre ou de parcourir le script du service worker et de voir si vous rencontrez des problèmes.

Capture d&#39;écran montrant où se trouve 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, il n'y a pas grand-chose à faire pour le résoudre, car vous n'avez aucun moyen de vérifier si Chrome a reçu quelque chose. L'essentiel est de vous assurer 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 un échec s'affiche, cela signifie qu'un problème est survenu avec l'ID d'enregistrement FCM et que le message push n'est pas envoyé à Chrome.

Déboguer les service workers sur Chrome pour Android

Pour le moment, le débogage des service workers dans Chrome pour Android n'est pas évident. Accédez à chrome://inspect, recherchez votre appareil et recherchez un élément de liste nommé "Worker pid:...", qui contient l'URL de votre service worker.

Capture d&#39;écran montrant où se trouvent les service workers dans Chrome Inspector

Expérience utilisateur pour les notifications push

L'équipe Chrome a rédigé un document sur les bonnes pratiques à suivre pour l'expérience utilisateur avec les notifications push, ainsi qu'un document couvrant certains des cas particuliers liés à l'utilisation des notifications push.

L'avenir des messages push dans Chrome et le Web ouvert

Cette section détaille certaines des parties de cette implémentation spécifiques à Chrome que vous devez connaître et en quoi elle diffère des autres implémentations du navigateur.

Protocole Web Push et points de terminaison

L'avantage de la norme de l'API Push est que vous devez pouvoir utiliser 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 push peuvent implémenter, ce qui permet aux développeurs de ne pas avoir à se soucier de leur identité. L'idée est qu'il n'est pas nécessaire de s'inscrire pour obtenir des clés API et d'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 requiert gcm_sender_id, et vous devez utiliser l'API REST 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 mettre en forme 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 protocole Push et sera probablement le premier navigateur à mettre en œuvre le protocole Web Push.

Questions fréquentes

Où se trouvent les caractéristiques techniques ?

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 sur le Web et d'une présence native ?

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

Le scénario idéal serait d'avoir une sorte d'ID pour l'appareil d'un utilisateur, puis, côté serveur, de faire correspondre les ID d'abonnement de l'application native et de l'application Web, et de décider à quel numéro envoyer un message push. Vous pouvez le faire via 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 présente des avantages et des inconvénients.

Pourquoi ai-je besoin d'un identifiant 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 une fois la norme finalisée et compatible avec FCM.

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

L'avantage des messages push est que même si votre page est fermée, votre service worker s'active et peut afficher une notification. La connexion des WebSockets et d'EventSource est fermée lorsque la page ou le navigateur sont fermés.

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

Si vous n'avez pas besoin d'une diffusion en arrière-plan, les Web Sockets constituent une excellente option.

Quand puis-je utiliser la fonction Push sans afficher de notifications (par exemple, push silencieuse en arrière-plan) ?

Il n'existe aucun calendrier pour la disponibilité de cette fonctionnalité, mais il existe un intent pour implémenter la synchronisation en arrière-plan. Bien que cela ne soit ni décidé, ni spécifié, il existe une discussion autour de l'activation du 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 ont besoin d'origines sécurisées pour s'assurer que leur script provient de l'origine prévue et qu'il ne provient pas d'une attaque MITM ("man in the middle"). Actuellement, cela implique d'utiliser HTTPS sur les sites en ligne, bien que localhost fonctionne pendant le développement.

À quoi ressemble la prise en charge du navigateur ?

Chrome est compatible avec sa version stable et Mozilla a été déployé dans Firefox Nightly. Pour en savoir plus, consultez la section concernant l'implémentation de l'API Push et suivez l'implémentation de la notification ici.

Puis-je supprimer une notification après un certain délai ?

Pour le moment, cela n'est pas possible, mais nous prévoyons d'ajouter cette fonctionnalité afin d'obtenir la liste des notifications actuellement visibles. Si vous voulez définir un délai d'expiration pour une notification après son affichage, nous aimerions en savoir plus. N'hésitez donc pas à ajouter un commentaire. Nous le transmettrons à l'équipe Chrome.

Si vous avez seulement besoin d'arrêter l'envoi d'une notification push à l'utilisateur après un certain temps et que vous ne vous souciez pas de la durée pendant laquelle elle reste visible, vous pouvez utiliser le paramètre FCM de valeur TTL (Time To Live). En savoir plus

Quelles sont les limites des messages push dans Chrome ?

Il y a certaines limites décrites dans cet article:

  • L'utilisation de CCM par Chrome en tant que service push engendre un certain nombre d'exigences propriétaires. Nous travaillons ensemble pour voir si certaines d'entre elles peuvent être améliorées à l'avenir.
  • Vous devez afficher une notification lorsque vous recevez un message push.
  • Dans Chrome sur ordinateur, la mise en garde : si Chrome n'est pas en cours d'exécution, les messages push ne seront pas reçus. Cela diffère de ChromeOS et Android, où les messages push sont toujours reçus.

Ne pourrions-nous pas utiliser l'API Permissions ?

L'API Permission est implémentée dans Chrome, mais elle ne sera 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 la notification push ?

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

En savoir plus

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

Dans FCM, vous disposez d'un paramètre "réduction_clé" qui permet de demander à FCM de remplacer par le nouveau message tout message en attente associé à la même clé "Réduire".

En savoir plus