Pushmeldingen op het open web

Als je een groep ontwikkelaars vraagt ​​welke functies van mobiele apparaten ontbreken op internet, staan ​​pushmeldingen altijd hoog op de lijst.

Met pushmeldingen kunnen uw gebruikers zich aanmelden voor tijdige updates van sites die zij leuk vinden en kunt u ze effectief opnieuw betrekken met aangepaste, boeiende inhoud.

Vanaf Chrome-versie 42 zijn de Push API en Notification API beschikbaar voor ontwikkelaars.

De Push API in Chrome is afhankelijk van een aantal verschillende soorten technologie, waaronder Web App Manifests en Service Workers . In dit bericht bekijken we elk van deze technologieën, maar alleen het absolute minimum om push-berichten operationeel te krijgen. Om een ​​beter inzicht te krijgen in enkele van de andere kenmerken van manifesten en de offline mogelijkheden van servicemedewerkers, kunt u de bovenstaande links bekijken.

We zullen ook kijken naar wat er in toekomstige versies van Chrome aan de API zal worden toegevoegd, en tot slot zullen we een FAQ hebben.

Pushberichten implementeren voor Chrome

In deze sectie wordt elke stap beschreven die u moet voltooien om pushberichten in uw webapp te ondersteunen.

Registreer een servicemedewerker

Er is een afhankelijkheid van het hebben van een servicemedewerker om push-berichten voor internet te implementeren. De reden hiervoor is dat wanneer een pushbericht wordt ontvangen, de browser een servicemedewerker kan opstarten, die op de achtergrond draait zonder dat er een pagina geopend is, en een gebeurtenis kan verzenden, zodat u kunt beslissen hoe u met dat pushbericht omgaat.

Hieronder ziet u een voorbeeld van hoe u een servicemedewerker registreert in uw webapp. Wanneer de registratie succesvol is voltooid, roepen we initialiseState() aan, wat we binnenkort zullen bespreken.

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.');
    }
});

De knopklikhandler schrijft de gebruiker in of uit voor pushberichten. isPushEnabled is een globale variabele die eenvoudigweg bijhoudt of pushberichten momenteel zijn geabonneerd of niet. Hiernaar wordt in de codefragmenten verwezen.

Vervolgens controleren we of servicemedewerkers worden ondersteund voordat we het bestand service-worker.js registreren, dat de logica bevat voor het afhandelen van een pushbericht. Hier vertellen we de browser eenvoudigweg dat dit JavaScript-bestand de servicemedewerker voor onze site is.

Stel de beginstatus in

Voorbeeld van ingeschakelde en uitgeschakelde push-berichten-UX in Chrome.

Zodra de servicemedewerker is geregistreerd, moeten we de status van onze gebruikersinterface instellen.

Gebruikers verwachten dat een eenvoudige gebruikersinterface pushberichten voor uw site in- of uitschakelt, en dat deze op de hoogte blijft van eventuele wijzigingen. Met andere woorden: als ze pushberichten voor uw site inschakelen, vertrekken en een week later terugkomen, moet uw gebruikersinterface aangeven dat pushberichten al zijn ingeschakeld.

In dit document vindt u enkele UX-richtlijnen . In dit artikel concentreren we ons op de technische aspecten.

Op dit punt denk je misschien dat er maar twee toestanden zijn om mee om te gaan: ingeschakeld of uitgeschakeld. Er zijn echter nog enkele andere statussen rond meldingen waarmee u rekening moet houden.

Een diagram waarin de verschillende overwegingen en de status van push in Chrome worden benadrukt

Er zijn een aantal API's die we moeten controleren voordat we onze knop inschakelen, en als alles wordt ondersteund, kunnen we onze gebruikersinterface inschakelen en de beginstatus instellen om aan te geven of push-berichten zijn geabonneerd of niet.

Aangezien het merendeel van deze controles ertoe leidt dat onze gebruikersinterface wordt uitgeschakeld, moet u de beginstatus op uitgeschakeld zetten. Dit voorkomt ook enige verwarring als er een probleem is met het JavaScript van uw pagina, bijvoorbeeld het JS-bestand kan niet worden gedownload of de gebruiker heeft JavaScript uitgeschakeld.

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

Met deze initiële status kunnen we de hierboven beschreven controles uitvoeren in de initialiseState() -methode, dat wil zeggen nadat onze servicemedewerker is geregistreerd.

// 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);
        });
    });
}

Een kort overzicht van deze stappen:

  • We controleren of showNotification beschikbaar is in het ServiceWorkerRegistration-prototype. Zonder deze kunnen wij geen melding van onze servicemedewerker tonen wanneer er een pushbericht wordt ontvangen.
  • We controleren wat de huidige Notification.permission is om er zeker van te zijn dat deze niet wordt "denied" . Een geweigerde toestemming betekent dat u geen meldingen kunt weergeven totdat de gebruiker de toestemming handmatig in de browser heeft gewijzigd.
  • Om te controleren of push-berichten worden ondersteund, controleren we of PushManager beschikbaar is in het vensterobject.
  • Ten slotte hebben we pushManager.getSubscription() gebruikt om te controleren of we al een abonnement hebben of niet. Als we dat doen, sturen we de abonnementsgegevens naar onze server om er zeker van te zijn dat we over de juiste informatie beschikken en stellen we onze gebruikersinterface in om aan te geven of pushberichten al zijn ingeschakeld of niet. We zullen verderop in dit artikel bekijken welke details er in het abonnementsobject voorkomen.

We wachten tot navigator.serviceWorker.ready is opgelost om te controleren op een abonnement en om de drukknop in te schakelen, omdat u zich pas daadwerkelijk kunt abonneren op pushberichten nadat de servicemedewerker actief is.

De volgende stap is het afhandelen wanneer de gebruiker pushberichten wil inschakelen, maar voordat we dit kunnen doen, moeten we een Google Developer Console-project opzetten en enkele parameters aan ons manifest toevoegen om Firebase Cloud Messaging (FCM) te gebruiken, voorheen bekend als Google Cloud Messaging (GCM).

Maak een project in de Firebase Developer Console

Chrome gebruikt FCM om het verzenden en bezorgen van pushberichten af ​​te handelen; Als u de FCM API wilt gebruiken, moet u echter een project instellen in de Firebase Developer Console.

De volgende stappen zijn specifiek voor Chrome, Opera voor Android en Samsung Browser waar ze FCM gebruiken. We zullen verderop in dit artikel bespreken hoe dit in andere browsers zou werken.

Maak een nieuw Firebase Developer-project

Om te beginnen moet u een nieuw project maken op https://console.firebase.google.com/ door op 'Nieuw project maken' te klikken.

Nieuwe Firebase-projectscreenshot

Voeg een projectnaam toe, maak het project aan en u wordt naar het projectdashboard geleid:

Firebase Project-startpagina

Vanuit dit dashboard klikt u op het tandwiel naast uw projectnaam in de linkerbovenhoek en klikt u op 'Projectinstellingen'.

Menu Firebase-projectinstellingen

Klik op de instellingenpagina op het tabblad 'Cloud Messaging'.

Firebase Project Cloud Messaging-menu

Deze pagina bevat de API-sleutel voor pushberichten, die we later zullen gebruiken, en de afzender-ID die we in het volgende gedeelte in het webapp-manifest moeten plaatsen.

Voeg een webapp-manifest toe

Voor push moeten we een manifestbestand toevoegen met het veld gcm_sender_id om het push-abonnement te laten slagen. Deze parameter is alleen vereist door Chrome, Opera voor Android en Samsung Browser zodat ze FCM / GCM kunnen gebruiken.

De gcm_sender_id wordt door deze browsers gebruikt wanneer een gebruikersapparaat wordt geabonneerd op FCM. Dit betekent dat FCM het apparaat van de gebruiker kan identificeren en ervoor kan zorgen dat uw afzender-ID overeenkomt met de bijbehorende API-sleutel en dat de gebruiker uw server toestemming heeft gegeven om push-berichten te verzenden.

Hieronder vindt u een supereenvoudig manifestbestand:

{
    "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>"
}

U moet de waarde gcm_sender_id instellen op de afzender-ID van uw Firebase-project.

Nadat u uw manifestbestand in uw project hebt opgeslagen (manifest.json is een goede naam), kunt u ernaar verwijzen vanuit uw HTML met de volgende tag in de kop van uw pagina.

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

Als u geen webmanifest met deze parameters toevoegt, krijgt u een uitzondering wanneer u probeert de gebruiker te abonneren op pushberichten, met de foutmelding "Registration failed - no sender id provided" of "Registration failed - permission denied" .

Abonneer u op pushberichten

Nu u een manifest heeft ingesteld, kunt u teruggaan naar de JavaScript-code van uw site.

Om u te abonneren, moet u de methode Subscribe() aanroepen op het PushManager- object, waartoe u toegang krijgt via ServiceWorkerRegistration .

Hierdoor wordt de gebruiker gevraagd om uw herkomst toestemming te geven om pushmeldingen te verzenden. Zonder deze toestemming kunt u zich niet succesvol abonneren.

Als de belofte die door de methode Subscribe() wordt geretourneerd, wordt opgelost, krijgt u een PushSubscription- object dat een endpoint bevat.

Het eindpunt moet voor elke gebruiker op uw server worden opgeslagen, omdat u deze op een later tijdstip nodig hebt om pushberichten te verzenden.

De volgende code abonneert de gebruiker op push-berichten:

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';
        }
        });
    });
}

Op dit punt is uw web-app klaar om een ​​push-bericht te ontvangen, hoewel er niets zal gebeuren totdat we een push-gebeurtenislistener toevoegen aan ons servicemedewerkerbestand.

Servicemedewerker Push-gebeurtenislistener

Wanneer een push-bericht wordt ontvangen (we zullen in de volgende sectie bespreken hoe u een push-bericht kunt verzenden), wordt er een push-gebeurtenis verzonden naar uw servicemedewerker, waarna u een melding moet weergeven.

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
    })
    );
});

Deze code registreert een push-gebeurtenislistener en geeft een melding weer met een vooraf gedefinieerde titel, hoofdtekst, pictogram en een meldingstag. Een subtiliteit die in dit voorbeeld moet worden benadrukt, is de methode event.waitUntil() . Deze methode neemt een belofte in zich op en verlengt de levensduur van een gebeurtenishandler (of kan worden gezien als het in leven houden van de servicemedewerker), totdat de belofte is vervuld ; In dit geval wordt de belofte doorgegeven aan event.waitUntil is de geretourneerde belofte van showNotification() .

De meldingstag fungeert als identificatie voor unieke meldingen. Als we twee pushberichten naar hetzelfde eindpunt hebben verzonden, met een korte vertraging ertussen, en meldingen met dezelfde tag weergeven, zal de browser de eerste melding weergeven en vervangen door de tweede melding wanneer het pushbericht wordt ontvangen.

Als je meerdere meldingen tegelijk wilt tonen, gebruik dan een andere tag, of helemaal geen tag. We zullen verderop in dit bericht een vollediger voorbeeld bekijken van het weergeven van een melding. Laten we het voorlopig simpel houden en kijken of bij het verzenden van een pushbericht deze melding wordt weergegeven.

Een pushbericht verzenden

We hebben ons geabonneerd op pushberichten en onze servicemedewerker staat klaar om een ​​melding te tonen, dus het is tijd om een ​​pushbericht te sturen via FCM.

Dit is alleen van toepassing op browsers die FCM gebruiken.

Wanneer u de variabele PushSubscription.endpoint naar uw server verzendt, is het eindpunt voor FCM speciaal. Het heeft een parameter aan het einde van de URL die een registration_id is.

Een voorbeeldeindpunt zou zijn:

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

De FCM-URL is:

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

De registration_id zou zijn:

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

Dit is specifiek voor browsers die FCM gebruiken. In een normale browser zou je eenvoudigweg een eindpunt krijgen en dat eindpunt op een standaardmanier aanroepen en het zou werken ongeacht de URL.

Wat dit betekent is dat u op uw server moet controleren of het eindpunt voor FCM is en als dit het geval is, moet u de registratie_id extraheren. Om dit in Python te doen, zou je zoiets kunnen doen als:

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

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

Zodra u de registratie-ID heeft, kunt u de FCM API aanroepen. U kunt hier referentiedocumenten over de FCM API vinden.

De belangrijkste aspecten waarmee u rekening moet houden als u FCM belt, zijn:

  • Een autorisatieheader met de waarde key=&lt;YOUR_API_KEY&gt; moet worden ingesteld wanneer u de API aanroept, waarbij &lt;YOUR_API_KEY&gt; is de API-sleutel van het Firebase-project.
    • De API-sleutel wordt door FCM gebruikt om de juiste afzender-ID te vinden, ervoor te zorgen dat de gebruiker toestemming heeft gegeven voor uw project en er ten slotte voor te zorgen dat het IP-adres van de server voor dat project op de toelatingslijst staat.
  • Een geschikte Content-Type header van application/json of application/x-www-form-urlencoded;charset=UTF-8 afhankelijk van of u de gegevens verzendt als JSON of als formuliergegevens.
  • Een reeks registration_ids : dit zijn de registratie-ID's die u uit de eindpunten van uw gebruikers haalt.

Bekijk alstublieft de documentatie over hoe u push-berichten vanaf uw server kunt verzenden, maar voor een snelle controle van uw servicemedewerker kunt u cURL gebruiken om een ​​push-bericht naar uw browser te verzenden.

Verwissel de &lt;YOUR_API_KEY&gt; en &lt;YOUR_REGISTRATION_ID&gt; in deze cURL-opdracht met uw eigen opdracht en voer deze uit vanaf een terminal.

Je zou een glorieuze melding moeten zien:

    curl --header "Authorization: key=<YOUR_API_KEY>" --header
    "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d
    "{\"registration_ids\":[\"<YOUR_REGISTRATION_ID>\"]}"
Voorbeeld van een pushbericht van Chrome voor Android.

Houd er bij het ontwikkelen van uw backend-logica rekening mee dat de autorisatieheader en het formaat van de POST-body specifiek zijn voor het FCM-eindpunt. Ontdek dus wanneer het eindpunt voor FCM is en voeg voorwaardelijk de header toe en formatteer de POST-body. Voor andere browsers (en hopelijk Chrome in de toekomst) moet je het Web Push Protocol implementeren.

Een minpunt aan de huidige implementatie van de Push API in Chrome is dat je met een pushbericht geen gegevens kunt versturen. Nee, niets. De reden hiervoor is dat bij een toekomstige implementatie de payloadgegevens op uw server moeten worden gecodeerd voordat deze naar een push-messaging-eindpunt worden verzonden. Op deze manier zal het eindpunt, welke pushprovider het ook is, de inhoud van het pushbericht niet gemakkelijk kunnen bekijken. Dit beschermt ook tegen andere kwetsbaarheden, zoals slechte validatie van HTTPS-certificaten en man-in-the-middle-aanvallen tussen uw server en de push-provider. Deze codering wordt echter nog niet ondersteund, dus in de tussentijd moet u een ophaalactie uitvoeren om de informatie te verkrijgen die nodig is om een ​​melding in te vullen.

Een completer voorbeeld van een push-evenement

De melding die we tot nu toe hebben gezien is vrij eenvoudig en wat de voorbeelden betreft, is deze behoorlijk slecht in het afdekken van een gebruiksscenario in de echte wereld.

Realistisch gezien zullen de meeste mensen wat informatie van hun server willen krijgen voordat ze de melding weergeven. Dit kunnen gegevens zijn om de titel en het bericht van de melding met iets specifieks te vullen, of een stap verder gaan en enkele pagina's of gegevens in de cache opslaan, zodat wanneer de gebruiker op de melding klikt, alles onmiddellijk beschikbaar is wanneer de browser wordt geopend, zelfs als het netwerk is op dat moment niet beschikbaar.

In de volgende code halen we enkele gegevens op van een API, converteren het antwoord naar een object en gebruiken dit om onze melding in te vullen.

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
        });
    })
    );
});

Het is de moeite waard om nogmaals te benadrukken dat de event.waitUntil() een belofte aanneemt die resulteert in de belofte die wordt geretourneerd door showNotification() , wat betekent dat onze gebeurtenislistener niet zal afsluiten totdat de asynchrone fetch() aanroep is voltooid en de melding wordt getoond.

U zult merken dat we zelfs als er een fout optreedt een melding tonen. Dit komt omdat als we dat niet doen, Chrome zijn eigen generieke melding zal tonen.

Een URL openen wanneer de gebruiker op een melding klikt

Wanneer de gebruiker op een melding klikt, wordt er een notificationclick gebeurtenis verzonden naar uw servicemedewerker. Binnen uw handler kunt u de juiste actie ondernemen, zoals de focus op een tabblad of het openen van een venster met een bepaalde URL:

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('/');
        }
    })
    );
});

In dit voorbeeld wordt de browser geopend naar de hoofdmap van de oorsprong van de site, door de focus op een bestaand tabblad van dezelfde oorsprong te leggen als dat bestaat, en anders een nieuw tabblad te openen.

Er is hier een bericht gewijd aan enkele dingen die u kunt doen met de Notification API .

Afmelden voor het apparaat van een gebruiker

U bent geabonneerd op het apparaat van een gebruiker en deze ontvangt pushberichten, maar hoe kunt u zich afmelden?

De belangrijkste dingen die nodig zijn om het abonnement van een gebruikersapparaat op te zeggen, zijn het aanroepen van de unsubscribe() -methode op het PushSubscription- object en het verwijderen van het eindpunt van uw servers (zodat u geen pushberichten verzendt waarvan u weet dat ze niet zullen worden ontvangen). De onderstaande code doet precies dit:

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);
        });
    });
}

Het abonnement up-to-date houden

Abonnementen kunnen niet meer synchroon lopen tussen FCM en uw server. Zorg ervoor dat uw server de antwoordtekst van de FCM API's send POST parseert, op zoek naar error:NotRegistered en canonical_id resultaten, zoals uitgelegd in de FCM-documentatie .

Abonnementen kunnen ook niet meer gesynchroniseerd zijn tussen de servicemedewerker en uw server. Nadat u zich succesvol hebt aangemeld/afgemeld, kan een slechte netwerkverbinding er bijvoorbeeld voor zorgen dat u uw server niet kunt bijwerken; of een gebruiker kan de toestemming voor meldingen intrekken, wat een automatische afmelding activeert. Behandel dergelijke gevallen door het resultaat van serviceWorkerRegistration.pushManager.getSubscription() periodiek te controleren (bijvoorbeeld bij het laden van de pagina) en dit te synchroniseren met de server. Mogelijk wilt u zich ook automatisch opnieuw abonneren als u geen abonnement meer heeft en Notification.permission == 'toegekend'.

In sendSubscriptionToServer() moet u overwegen hoe u omgaat met mislukte netwerkverzoeken bij het bijwerken van het endpoint . Eén oplossing is om de status van het endpoint in een cookie bij te houden om te bepalen of uw server de nieuwste gegevens nodig heeft of niet.

Alle bovenstaande stappen resulteren in een volledige implementatie van pushberichten op internet in Chrome 46. Er zijn nog steeds gespecificeerde functies die de zaken eenvoudiger zullen maken (zoals een standaard API voor het activeren van pushberichten), maar met deze release kunt u beginnen vandaag nog push-berichten in uw web-apps inbouwen.

Hoe u fouten in uw webapp kunt opsporen

Tijdens het implementeren van pushberichten kunnen bugs zich op twee plaatsen bevinden: uw pagina of uw servicemedewerker.

Bugs op de pagina kunnen worden opgespoord met behulp van DevTools . Om problemen met servicemedewerkers op te lossen, heeft u twee opties:

  1. Ga naar chrome://inspect > Servicemedewerkers . Deze weergave biedt niet veel andere informatie dan de momenteel actieve servicewerknemers.
  2. Ga naar chrome://serviceworker-internals en vanaf hier kunt u de status van servicewerkers bekijken en eventuele fouten bekijken. Deze pagina is tijdelijk totdat DevTools een vergelijkbare functieset heeft.

Een van de beste tips die ik kan geven aan iedereen die nieuw is bij servicemedewerkers, is gebruik maken van het selectievakje "Open DevTools-venster en pauzeer de uitvoering van JavaScript bij het opstarten van servicemedewerkers voor foutopsporing." Dit selectievakje voegt een breekpunt toe aan het begin van uw service worker en pauzeert de uitvoering . Hierdoor kunt u uw service worker-script hervatten of doorlopen en kijken of u problemen ondervindt.

Schermafbeelding die laat zien waar het selectievakje voor het onderbreken van de uitvoering zich bevindt op serviceworker-internals.

Als er een probleem lijkt te zijn tussen FCM en de push-gebeurtenis van uw servicemedewerker, kunt u niet veel doen om het probleem op te lossen, omdat u op geen enkele manier kunt zien of Chrome iets heeft ontvangen. Het belangrijkste om ervoor te zorgen is dat de reactie van FCM succesvol is wanneer uw server een API-aanroep doet. Het zal er ongeveer zo uitzien:

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

Let op het "success": 1 reactie. Als u in plaats daarvan een fout ziet, duidt dit erop dat er iets niet klopt met de FCM-registratie-ID en dat het pushbericht niet naar Chrome wordt verzonden.

Foutopsporing voor servicemedewerkers in Chrome voor Android

Op dit moment is het debuggen van servicemedewerkers op Chrome voor Android niet vanzelfsprekend. U moet naar chrome://inspect navigeren, uw apparaat zoeken en naar een lijstitem zoeken met de naam 'Worker pid:...', dat de URL van uw servicemedewerker bevat.

Schermafbeelding die laat zien waar servicemedewerkers wonen in Chrome-inspectie

UX voor pushmeldingen

Het Chrome-team heeft een document samengesteld met best practices voor pushmeldingen UX, evenals een document dat enkele van de randgevallen behandelt bij het werken met pushmeldingen.

Toekomst van pushberichten in Chrome en het open web

In dit gedeelte wordt dieper ingegaan op enkele Chrome-specifieke onderdelen van deze implementatie waarvan u op de hoogte moet zijn en hoe deze zal verschillen van andere browserimplementaties.

Web Push Protocol en eindpunten

Het mooie van de Push API-standaard is dat u het eindpunt kunt overnemen, deze kunt doorgeven aan uw server en push-berichten kunt verzenden door het Web Push Protocol te implementeren.

Het Web Push Protocol is een nieuwe standaard die pushproviders kunnen implementeren, waardoor ontwikkelaars zich geen zorgen hoeven te maken over wie de pushprovider is. Het idee is dat dit de noodzaak vermijdt om zich aan te melden voor API-sleutels en speciaal opgemaakte gegevens te verzenden, zoals bij FCM.

Chrome was de eerste browser die de Push API implementeerde en FCM ondersteunt het Web Push Protocol niet. Dit is de reden waarom Chrome de gcm_sender_id vereist en u de restful API voor FCM moet gebruiken.

Het einddoel voor Chrome is om over te gaan naar het gebruik van het Web Push Protocol met Chrome en FCM.

Tot die tijd moet u het eindpunt "https://fcm.googleapis.com/fcm/send" detecteren en afzonderlijk van andere eindpunten verwerken, dat wil zeggen de payloadgegevens op een specifieke manier formatteren en de autorisatiesleutel toevoegen.

Hoe implementeer ik het Web Push Protocol?

Firefox Nightly werkt momenteel aan push en zal waarschijnlijk de eerste browser zijn die het Web Push Protocol implementeert.

Veelgestelde vragen

Waar zijn de specificaties?

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

Kan ik dubbele meldingen voorkomen als mijn aanwezigheid op het web meerdere oorsprongen heeft, of als ik zowel een web- als een native aanwezigheid heb?

Er is momenteel geen oplossing hiervoor, maar je kunt de voortgang volgen op Chromium .

Het ideale scenario zou zijn om een ​​soort ID te hebben voor het apparaat van een gebruiker en vervolgens aan de serverzijde de native app- en webapp-abonnements-ID's met elkaar te vergelijken en te beslissen naar wie een pushbericht moet worden gestuurd. Je zou dit kunnen doen via schermgrootte, apparaatmodel, het delen van een gegenereerde sleutel tussen de webapp en de native app, maar elke aanpak heeft voor- en nadelen.

Waarom heb ik een gcm_sender_id nodig?

Dit is vereist zodat Chrome, Opera voor Android en de Samsung Browser de Firebase Cloud Messaging (FCM) API kunnen gebruiken. Het doel is om het Web Push Protocol te gebruiken wanneer de standaard gereed is en FCM deze kan ondersteunen.

Waarom zou u geen Web Sockets of Server-Sent Events (EventSource) gebruiken?

Het voordeel van het gebruik van pushberichten is dat zelfs als uw pagina gesloten is, uw servicemedewerker gewekt wordt en een melding kan tonen. Web Sockets en EventSource hebben hun verbinding gesloten wanneer de pagina of browser wordt gesloten.

Wat moet ik doen als ik geen levering van achtergrondgebeurtenissen nodig heb?

Als u geen levering op de achtergrond nodig heeft, zijn Web Sockets een goede optie.

Wanneer kan ik push gebruiken zonder meldingen te tonen (dwz stille push op de achtergrond)?

Er is nog geen tijdlijn voor wanneer dit beschikbaar zal zijn, maar er is een intentie om achtergrondsynchronisatie te implementeren en hoewel dit nog niet besloten of gespecificeerd is, is er enige discussie over het inschakelen van stille push met achtergrondsynchronisatie.

Waarom is hiervoor HTTPS nodig? Hoe kan ik dit tijdens de ontwikkeling omzeilen?

Servicewerknemers hebben een veilige oorsprong nodig om ervoor te zorgen dat het servicewerknemerscript afkomstig is van de beoogde oorsprong en niet het gevolg is van een man-in-the-middle-aanval. Momenteel betekent dit het gebruik van HTTPS op live sites, hoewel localhost tijdens de ontwikkeling zal werken.

Hoe ziet browserondersteuning eruit?

Chrome ondersteunt in de stabiele versie en Mozilla heeft push waaraan gewerkt wordt in Firefox Nightly. Zie de implementatie van de Push API- bug voor meer informatie en je kunt de implementatie van hun meldingen hier volgen.

Kan ik een melding na een bepaalde periode verwijderen?

Op dit moment is dit niet mogelijk, maar we zijn van plan ondersteuning toe te voegen om een ​​lijst met momenteel zichtbare meldingen te krijgen. Als u een gebruiksscenario heeft om een ​​vervaldatum in te stellen voor meldingen nadat deze zijn gemaakt, willen we graag weten wat dat is. Voeg daarom een ​​opmerking toe, zodat we dit terugsturen naar het Chrome-team.

Als u pas na een bepaalde tijd wilt voorkomen dat een pushmelding naar de gebruiker wordt verzonden, en het u niet uitmaakt hoe lang de melding zichtbaar blijft, kunt u de time to live (ttl)-parameter van FCM gebruiken. Lees hier meer .

Wat zijn de beperkingen van pushberichten in Chrome?

Er zijn een paar beperkingen die in dit bericht worden beschreven:

  • Het gebruik door Chrome van CCM als push-service creëert een aantal eigen vereisten. We werken samen om te zien of een aantal hiervan in de toekomst kunnen worden opgeheven.
  • Wanneer u een pushbericht ontvangt, moet u een melding tonen.
  • Chrome op desktop heeft het voorbehoud dat als Chrome niet actief is, er geen pushberichten worden ontvangen. Dit wijkt af van ChromeOS en Android waar pushberichten altijd ontvangen worden.

Moeten we niet de Permissions API gebruiken?

De Permission API is geïmplementeerd in Chrome, maar zal niet noodzakelijkerwijs in alle browsers beschikbaar zijn. Hier kunt u meer informatie vinden .

Waarom opent Chrome het vorige tabblad niet als ik op een melding klik?

Dit probleem heeft alleen betrekking op pagina's die momenteel niet worden beheerd door een servicemedewerker. Hier kunt u meer informatie vinden .

Wat moet ik doen als een melding verouderd is op het moment dat het apparaat van de gebruiker de push ontvangt?

Je moet altijd een melding tonen als je een pushbericht ontvangt. In het scenario waarin u een melding wilt verzenden, maar deze alleen voor een bepaalde periode nuttig is, kunt u de parameter 'time_to_live' op CCM gebruiken, zodat FCM het pushbericht niet verzendt als de vervaltijd is verstreken.

Meer details vindt u hier .

Wat gebeurt er als ik 10 pushberichten verstuur, maar wil dat het apparaat er slechts één ontvangt?

FCM heeft een 'collapse_key'-parameter die u kunt gebruiken om FCM te vertellen elk wachtend bericht dat dezelfde 'collapse_key' heeft, te vervangen door het nieuwe bericht.

Meer details vindt u hier .