Açık Web'de Push Bildirimleri

Matt Gaunt

Bir grup geliştiriciye web'de hangi mobil cihaz özelliklerinin eksik olduğunu sorarsanız push bildirimleri her zaman listenin üst sıralarında yer alır.

Push bildirimleri, kullanıcılarınızın sevdikleri sitelerden zamanında güncellemeler almasını sağlar ve özelleştirilmiş, ilgi çekici içeriklerle onlarla etkili bir şekilde yeniden etkileşim kurmanıza olanak tanır.

Chrome 42 sürümü itibarıyla Push API ve Notification API geliştiriciler tarafından kullanılabilir.

Chrome'daki Push API, Web Uygulama Manifestleri ve Hizmet Çalışanları gibi birkaç farklı teknolojiyi kullanır. Bu yayında, bu teknolojilerin her birine bakacağız ancak yalnızca push mesajlaşmayı kullanmaya başlamak için gereken minimum düzeyde bilgi vereceğiz. Manifestlerin diğer özelliklerinden bazılarını ve servis çalışanlarının çevrimdışı özelliklerini daha iyi anlamak için lütfen yukarıdaki bağlantılara göz atın.

Ayrıca, Chrome'un gelecekteki sürümlerinde API'ye neler ekleneceğine de bakacağız. Son olarak, SSS bölümüne göz atacağız.

Chrome için Push Mesajlaşma'yı uygulama

Bu bölümde, web uygulamanızda push mesajlaşmayı desteklemek için tamamlamanız gereken her adım açıklanmaktadır.

Hizmet Çalışanı kaydetme

Web için push mesajları uygulamak üzere bir hizmet çalışanına ihtiyaç vardır. Bunun nedeni, bir push mesajı alındığında tarayıcının, sayfa açık olmadan arka planda çalışan bir hizmet çalışanı başlatabilmesi ve bu push mesajını nasıl işleyeceğinize karar verebilmeniz için bir etkinlik göndermesidir.

Aşağıda, web uygulamanıza nasıl hizmet çalışanı kaydettiğinize dair bir örnek verilmiştir. Kayıt işlemi başarıyla tamamlandığında initialiseState() işlevini çağırırız. Bu işlevi kısa süre içinde ele alacağız.

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

Düğme tıklama işleyicisi, kullanıcıyı push mesajlarına abone eder veya kullanıcının aboneliğini iptal eder. isPushEnabled, push mesajlarının şu anda abone olup olmadığını izleyen genel bir değişkendir. Bunlar, kod snippet'lerinde referans olarak kullanılır.

Ardından, push mesajını işleme mantığını içeren service-worker.js dosyasını kaydettirmeden önce service worker'ların desteklenip desteklenmediğini kontrol ederiz. Burada, tarayıcıya bu JavaScript dosyasının sitemizin hizmet çalışanı olduğunu söylüyoruz.

İlk Durumu Ayarlama

Chrome'da etkin ve devre dışı push mesajlaşma kullanıcı deneyimi örneği.

Hizmet çalışanı kaydedildikten sonra kullanıcı arayüzünün durumunu ayarlamamız gerekir.

Kullanıcılar, siteniz için push mesajlarını etkinleştirmek veya devre dışı bırakmak üzere basit bir kullanıcı arayüzü bekler ve bu arayüzün gerçekleşen tüm değişikliklerle güncel kalmasını ister. Diğer bir deyişle, siteniz için push mesajlarını etkinleştirirlerse siteden ayrılıp bir hafta sonra geri geldiğinizde kullanıcı arayüzünüzde push mesajlarının zaten etkin olduğu vurgulanır.

Bu dokümanda kullanıcı deneyimi yönergeleri bulabilirsiniz. Bu makalede, teknik yönlere odaklanacağız.

Bu noktada, yalnızca etkin veya devre dışı olmak üzere iki durum olduğunu düşünebilirsiniz. Ancak bildirimler konusunda dikkate almanız gereken başka durumlar da vardır.

Chrome'daki farklı hususları ve push'ın durumunu vurgulayan bir şema

Düğmemizi etkinleştirmeden önce kontrol etmemiz gereken birkaç API vardır. Her şey destekleniyorsa kullanıcı arayüzümüz etkinleştirebilir ve push mesajlarının abone olup olmadığını belirtmek için ilk durumu ayarlayabiliriz.

Bu kontrollerin çoğu kullanıcı arayüzünün devre dışı bırakılmasına neden olduğundan ilk durumu devre dışı olarak ayarlamanız gerekir. Bu, sayfanızdaki JavaScript ile ilgili bir sorun (ör. JS dosyası indirilemiyor veya kullanıcı JavaScript'i devre dışı bırakmış) olması durumunda da karışıklığı önler.

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

Bu ilk durumda, initialiseState() yönteminde yukarıda belirtilen kontrolleri (yani hizmet işleyicimiz kaydedildikten sonra) gerçekleştirebiliriz.

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

Bu adımlara kısaca göz atın:

  • showNotification değerinin ServiceWorkerRegistration prototipinde mevcut olup olmadığını kontrol ederiz. Bu olmadan, bir push mesajı alındığında hizmet çalışanımızdan bildirim gösteremeyiz.
  • "denied" olmadığından emin olmak için mevcut Notification.permission değerini kontrol ederiz. İzin reddedildiğinde, kullanıcı tarayıcıda izni manuel olarak değiştirene kadar bildirim gösteremezsiniz.
  • Push mesajlaşmanın desteklenip desteklenmediğini kontrol etmek için pencere nesnesinde PushManager öğesinin mevcut olup olmadığını kontrol ederiz.
  • Son olarak, aboneliğimizin olup olmadığını kontrol etmek için pushManager.getSubscription() değerini kullandık. Bu durumda, doğru bilgilere sahip olduğumuzdan emin olmak için abonelik ayrıntılarını sunucumuza gönderir ve kullanıcı arayüzümüze push mesajlaşmanın etkin olup olmadığını belirtecek şekilde ayar yaparız. Abonelik nesnesinde bulunan ayrıntıları bu makalenin ilerleyen bölümlerinde inceleyeceğiz.

Aboneliği kontrol etmek ve push düğmesini etkinleştirmek için navigator.serviceWorker.ready sorununun çözülmesini bekleriz. Çünkü push mesajlarına yalnızca hizmet çalışanı etkin olduktan sonra abone olabilirsiniz.

Bir sonraki adım, kullanıcının push mesajlarını etkinleştirmek istemesi durumunda bu işlemi gerçekleştirmektir. Ancak bunu yapabilmemiz için önce bir Google Developers Console projesi oluşturmamız ve eski adıyla Google Cloud Messaging (GCM) olan Firebase Cloud Messaging (FCM)'i kullanmak için manifest dosyamıza bazı parametreler eklememiz gerekir.

Firebase Geliştirici Konsolu'nda Proje Oluşturma

Chrome, push mesajlarının gönderilmesini ve teslim edilmesini yönetmek için FCM'yi kullanır. Ancak FCM API'yi kullanmak için Firebase Developer Console'da bir proje oluşturmanız gerekir.

Aşağıdaki adımlar, FCM kullanan Chrome, Android için Opera ve Samsung Tarayıcı'ya özeldir. Bu özelliğin diğer tarayıcılarda nasıl çalıştığını makalenin ilerleyen bölümlerinde ele alacağız.

Yeni bir Firebase geliştirici projesi oluşturma

Başlamak için https://console.firebase.google.com/ adresinde "Yeni Proje Oluştur"u tıklayarak yeni bir proje oluşturmanız gerekir.

Yeni Firebase Projesi Ekran Görüntüsü

Proje adı ekleyin, projeyi oluşturun. Ardından proje kontrol paneline yönlendirilirsiniz:

Firebase Projesi Ana Sayfası

Bu kontrol panelinde, sol üst köşedeki proje adınızın yanındaki dişli çarkı ve ardından "Proje Ayarları"nı tıklayın.

Firebase Proje Ayarları Menüsü

Ayarlar sayfasında "Bulut Mesajları" sekmesini tıklayın.

Firebase Projesi Cloud Messaging Menüsü

Bu sayfada, daha sonra kullanacağımız push mesajları için API anahtarı ve sonraki bölümde web uygulaması manifest dosyasına eklememiz gereken gönderen kimliği yer alır.

Web uygulaması manifesti ekleme

Push için, push aboneliğinin başarılı olması amacıyla gcm_sender_id alanı içeren bir manifest dosyası eklememiz gerekir. Bu parametre yalnızca Chrome, Android için Opera ve Samsung Tarayıcı'nın FCM / GCM'yi kullanabilmesi için gereklidir.

gcm_sender_id, kullanıcının cihazını FCM'ye abone ederken bu tarayıcılar tarafından kullanılır. Bu, FCM'nin kullanıcının cihazını tanımlayabileceği ve gönderen kimliğinizin ilgili API anahtarıyla eşleştiğinden ve kullanıcının sunucunuzun kendisine push mesajı göndermesine izin verdiğinden emin olabileceği anlamına gelir.

Aşağıda son derece basit bir manifest dosyası verilmiştir:

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

gcm_sender_id değerini Firebase projenizdeki gönderen kimliğine ayarlamanız gerekir.

Manifest dosyanızı projenize kaydettikten sonra (manifest.json iyi bir addır), sayfanızı başlığında aşağıdaki etiketle HTML'nizde referans olarak kullanın.

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

Bu parametreleri içeren bir web manifesti eklemezseniz kullanıcıyı push mesajlarına abone etmeye çalışırken "Registration failed - no sender id provided" veya "Registration failed - permission denied" hata mesajıyla birlikte bir istisna alırsınız.

Push Mesajlaşma'ya abone olma

Bir manifest oluşturdunuz. Artık sitenizin JavaScript'ine geri dönebilirsiniz.

Abone olmak için ServiceWorkerRegistration aracılığıyla eriştiğiniz PushManager nesnesinde subscribe() yöntemini çağırmanız gerekir.

Bu işlem, kullanıcıdan kaynak izni vererek push bildirimleri göndermenizi ister. Bu izin olmadan abone olamazsınız.

subscribe() yöntemi tarafından döndürülen promise çözülürse bir uç nokta içeren bir PushSubscription nesnesi alırsınız.

Daha sonra push mesajları göndermek için bu uç noktaları her kullanıcı için sunucunuza kaydedilmelidir.

Aşağıdaki kod, kullanıcıyı push mesajları için kaydetmektedir:

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

Bu noktada web uygulamanız push mesajı almaya hazırdır ancak hizmet çalışanı dosyamıza bir push etkinliği dinleyici ekleyene kadar hiçbir şey olmaz.

Hizmet Çalışanı Push Etkinliği İşleyici

Bir push mesajı alındığında (push mesajının nasıl gönderileceğinden sonraki bölümde bahsedeceğiz) hizmet çalışanınızda bir push etkinliği gönderilir. Bu noktada bir bildirim göstermeniz gerekir.

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

Bu kod, bir push etkinliği dinleyicisi kaydeder ve önceden tanımlanmış bir başlık, gövde metni, simge ve bildirim etiketi içeren bir bildirim görüntüler. Bu örnekte vurgulanabilecek bir ayrıntı, event.waitUntil() yöntemidir. Bu yöntem, bir promise alır ve promise çözüme ulaştırılana kadar bir etkinlik işleyicinin ömrünü uzatır (veya hizmet işleyicinin etkin kalmasını sağlar). Bu durumda, event.waitUntil'e iletilen promise, showNotification()'ten döndürülen Promise'dir.

Bildirim etiketi, benzersiz bildirimler için tanımlayıcı görevi görür. Aynı uç noktaya, aralarında kısa bir gecikme olacak şekilde iki push mesajı gönderirsek ve bildirimleri aynı etiketle gösterirsek tarayıcı ilk bildirimi gösterir ve push mesajı alındığında bunu ikinci bildirimle değiştirir.

Aynı anda birden fazla bildirim göstermek istiyorsanız farklı bir etiket kullanın veya hiç etiket kullanmayın. Bildirim göstermeyle ilgili daha kapsamlı bir örneği bu yayının ilerleyen bölümlerinde inceleyeceğiz. Şimdilik işleri basit tutalım ve bir push mesajı göndererek bu bildirimin gösterilip gösterilmediğini kontrol edelim.

Push mesajı gönderme

Push mesajlarına abone olduk ve hizmet işleyicimiz bildirim göstermeye hazır. Artık FCM üzerinden push mesajı gönderme zamanı geldi.

Bu yalnızca FCM kullanan tarayıcılar için geçerlidir.

PushSubscription.endpoint değişkenini sunucunuza gönderdiğinizde FCM için uç nokta özeldir. URL'nin sonunda registration_id olan bir parametre var.

Örnek bir uç nokta:

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

FCM URL'si:

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

registration_id şu şekilde olur:

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

Bu durum, FCM kullanan tarayıcılara özeldir. Normal bir tarayıcıda, bir uç nokta alır ve bu uç noktayı standart bir şekilde çağırırsınız. Bu işlem, URL'den bağımsız olarak çalışır.

Bu, sunucunuzda uç noktanın FCM için olup olmadığını kontrol etmeniz ve FCM içinse registration_id değerini çıkarmanız gerektiği anlamına gelir. Bunu Python'da yapmak için aşağıdaki gibi bir şey yapabilirsiniz:

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

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

Kayıt kimliğini aldıktan sonra FCM API'yi çağırabilirsiniz. FCM API ile ilgili referans dokümanlarını burada bulabilirsiniz.

FCM'yi çağırırken dikkat edilmesi gereken önemli noktalar şunlardır:

  • API'yi çağırırken key=&lt;YOUR_API_KEY&gt; değerine sahip bir Authorization başlığı ayarlanmalıdır. Burada &lt;YOUR_API_KEY&gt;, Firebase projesindeki API anahtarıdır.
    • API anahtarı, FCM tarafından uygun gönderen kimliğini bulmak, kullanıcının projeniz için izin verdiğinden emin olmak ve son olarak sunucunun IP adresinin ilgili proje için izin verilenler listesine eklendiğinden emin olmak için kullanılır.
  • Verileri JSON olarak mı yoksa form verileri olarak mı gönderdiğinize bağlı olarak uygun bir Content-Type application/json veya application/x-www-form-urlencoded;charset=UTF-8 başlığı.
  • registration_ids dizisi: Kullanıcılarınızın uç noktalarından ayıklayacağınız kayıt kimlikleridir.

Sunucunuzdan push mesajı gönderme hakkında dokümanlara göz atın. Ancak servis çalışanınızı hızlıca kontrol etmek için tarayıcınızla push mesajı göndermek üzere cURL'ı kullanabilirsiniz.

Bu cURL komutundaki &lt;YOUR_API_KEY&gt; ve &lt;YOUR_REGISTRATION_ID&gt; değerlerini kendi değerlerinizle değiştirin ve komutu bir terminalden çalıştırın.

Aşağıdaki gibi bir bildirim görürsünüz:

    curl --header "Authorization: key=<YOUR_API_KEY>" --header
    "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d
    "{\"registration_ids\":[\"<YOUR_REGISTRATION_ID>\"]}"
Android için Chrome&#39;dan gelen bir push mesajı örneği.

Arka uç mantığınızı geliştirirken, POST gövdesinin Authorization üstbilgisinin ve biçiminin FCM uç noktasına özgü olduğunu unutmayın. Bu nedenle, uç noktasının FCM için ne zaman olduğunu algılayın ve üstbilgiyi koşullu olarak ekleyin ve POST gövdesini biçimlendirin. Diğer tarayıcılarda (ve umarım gelecekte Chrome'da) Web Push Protokolü'nü uygulamanız gerekir.

Chrome'da Push API'nin mevcut uygulamasının dezavantajı, push mesajıyla veri gönderememenizdir. Hayır, hiçbir şey. Bunun nedeni, gelecekteki bir uygulamada yük verilerinin bir push mesajlaşma uç noktasına gönderilmeden önce sunucunuzda şifrelenmesinin gerekmesidir. Bu sayede uç nokta (push sağlayıcısı ne olursa olsun) push mesajının içeriğini kolayca görüntüleyemez. Bu, HTTPS sertifikalarının zayıf doğrulanması ve sunucunuz ile push sağlayıcısı arasındaki ortadaki adam saldırıları gibi diğer güvenlik açıklarına karşı da koruma sağlar. Ancak bu şifreleme henüz desteklenmemektedir. Bu nedenle, bir bildirimi doldurmak için gereken bilgileri almak üzere bu süre zarfında getirme işlemi yapmanız gerekir.

Daha kapsamlı bir push etkinliği örneği

Şimdiye kadar gördüğümüz bildirim oldukça basit ve örnekler açısından gerçek bir kullanım alanını kapsama konusunda oldukça zayıf.

Gerçekçi olmak gerekirse çoğu kullanıcı, bildirimi göstermeden önce sunucularından bilgi almak ister. Bu veriler, bildirim başlığını ve mesajını belirli bir içerikle doldurmak için kullanılabilir. Bir adım daha ileri gidip bazı sayfaları veya verileri önbelleğe alarak da kullanıcı bildirimi tıkladığında ağ o anda kullanılamıyor olsa bile tarayıcı açıldığında her şeyin hemen kullanılabilir olmasını sağlayabilirsiniz.

Aşağıdaki kodda bir API'den bazı veriler getirir, yanıtı bir nesneye dönüştürür ve bildirimimizi doldurmak için kullanırız.

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

event.waitUntil()'ün bir promise aldığını ve bunun sonucunda showNotification() tarafından promise döndürüldüğünü bir kez daha vurgulamak gerekir. Diğer bir deyişle, etkinlik işleyicimiz, asenkron fetch() çağrısı tamamlanana ve bildirim gösterilene kadar sona ermez.

Hata olduğunda bile bildirim gösterildiğini fark edeceksiniz. Bunun nedeni, bunu yapmazsak Chrome'un kendi genel bildirimini göstermesidir.

Kullanıcı bir bildirimi tıkladığında URL açma

Kullanıcı bir bildirimi tıkladığında hizmet çalışanınızda bir notificationclick etkinliği gönderilir. İşleyicinizde, bir sekmeye odaklanma veya belirli bir URL'ye sahip bir pencere açma gibi uygun işlemleri yapabilirsiniz:

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

Bu örnekte, tarayıcı aynı kaynaktaki mevcut bir sekmeye odaklanarak (varsa) sitenin kaynağının kökünde açılır. Aksi takdirde yeni bir sekme açılır.

Bildirim API'si ile yapabileceğiniz bazı işlemlere buradan ulaşabilirsiniz.

Kullanıcının cihazının e-posta listesinden çıkması

Bir kullanıcının cihazını abone ettiniz ve kullanıcı push mesajları alıyor. Kullanıcının aboneliğini nasıl iptal edebilirsiniz?

Kullanıcının cihazının aboneliğini iptal etmek için gereken temel işlemler, PushSubscription nesnesinde unsubscribe() yöntemini çağırmak ve uç noktayı sunucularınızdan kaldırmaktır (alınmayacağını bildiğiniz push mesajları göndermemek için). Aşağıdaki kod tam olarak bunu yapar:

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

Aboneliği Güncel Tutma

Abonelikler, FCM ile sunucunuz arasında senkronize edilmeyebilir. Sunucunuzun, FCM dokümanlarında açıklandığı gibi, FCM API'nin gönder POST işleminin yanıt gövdesini ayrıştırıp error:NotRegistered ve canonical_id sonuçlarını aradığından emin olun.

Abonelikler, hizmet çalışanı ile sunucunuz arasında senkronize olmayabilir. Örneğin, başarılı bir şekilde abone olduktan/abonelikten çıktıktan sonra, kararsız bir ağ bağlantısı sunucunuzu güncellemenizi engelleyebilir veya bir kullanıcı, otomatik olarak abonelikten çıkmayı tetikleyen bildirim iznini iptal edebilir. serviceWorkerRegistration.pushManager.getSubscription() sonucunu düzenli aralıklarla (ör. sayfa yüklendiğinde) kontrol edip sunucuda senkronize ederek bu tür durumları ele alın. Aboneliğiniz yoksa ve Notification.permission == "granted" ise otomatik olarak yeniden abone olmayı da tercih edebilirsiniz.

sendSubscriptionToServer() içinde, endpoint'ı güncellerken başarısız ağ isteklerini nasıl ele alacağınızı düşünmeniz gerekir. Sunucunuzun en son ayrıntılara ihtiyacı olup olmadığını belirlemek için bir çözüm, çerezdeki endpoint durumunu izlemek olabilir.

Yukarıdaki adımların tümü, Chrome 46'ta web'de push mesajlaşmanın tam olarak uygulanmasına neden olur. İşleri kolaylaştıracak spesifik özellikler (ör. push mesajları tetiklemek için standart bir API) hâlâ mevcut olsa da bu sürüm, web uygulamalarınıza push mesajları eklemeye hemen başlamanızı sağlar.

Web Uygulamanızda Hata Ayıklama

Push mesajları uygulanırken hatalar iki yerden birinde bulunur: sayfanız veya servis çalışanınız.

Sayfadaki hatalarda DevTools kullanılarak hata ayıklama yapılabilir. Hizmet çalışanı sorunlarını gidermek için iki seçeneğiniz vardır:

  1. chrome://inspect > Service workers (Hizmet çalışanları) bölümüne gidin. Bu görünüm, şu anda çalışan hizmet işçileri dışında fazla bilgi sağlamaz.
  2. chrome://serviceworker-internals adresine giderek hizmet çalışanlarının durumunu ve varsa hataları görebilirsiniz. DevTools'ta benzer bir özellik grubu bulunana kadar bu sayfa geçicidir.

Hizmet işçileriyle yeni tanışan kullanıcılara verebileceğim en iyi ipuçlarından biri, "Hata ayıklama için DevTools penceresini açın ve hizmet işçisi başlatılırken JavaScript yürütmeyi duraklatın" adlı onay kutusunu kullanmaktır. Bu onay kutusu, hizmet çalışanınızın başına bir kesme noktası ekler ve yürütmeyi duraklatır. Bu sayede, hizmet çalışanı komut dosyanızı devam ettirebilir veya adım adım inceleyebilir ve herhangi bir sorunla karşılaşıp karşılaşmadığınızı görebilirsiniz.

serviceworker-internals&#39;da yürütmeyi duraklatma onay kutusunun nerede olduğunu gösteren ekran görüntüsü.

FCM ile hizmet çalışanınızın push etkinliği arasında bir sorun olduğu anlaşılıyorsa Chrome'un herhangi bir şey alıp almadığını göremediğiniz için sorunda hata ayıklama yapmak için pek bir şey yapamazsınız. Sunucunuz API çağrısı yaptığında FCM'den gelen yanıtın başarılı olduğundan emin olmanız gerekir. Bu, aşağıdaki gibi görünür:

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

"success": 1 yanıtına dikkat edin. Bunun yerine bir hata görürseniz FCM kayıt kimliğiyle ilgili bir sorun olduğu ve push mesajının Chrome'a gönderilmediği anlamına gelir.

Android için Chrome'da Hizmet Çalışanları'nda hata ayıklama

Android için Chrome'da hizmet işçileriyle ilgili hata ayıklama şu anda mümkün değildir. chrome://inspect adresine gidip cihazınızı bulmanız ve "İşleyici pid:...." adlı, servis işleyicinizin URL'sini içeren bir liste öğesi aramanız gerekir.

Chrome&#39;da hizmet işçilerinin bulunduğu yeri gösteren ekran görüntüsü

Push Bildirimleri İçin Kullanıcı Deneyimi

Chrome ekibi, push bildirimleri kullanıcı deneyimi ile ilgili en iyi uygulamalara ve push bildirimleriyle çalışırken karşılaşılabilecek bazı uç durumları kapsayan bir doküman hazırlıyor.

Chrome ve Açık Web'de Push Mesajlarının Geleceği

Bu bölümde, bu uygulamanın Chrome'a özgü bazı bölümleriyle ilgili bilmeniz gerekenler ve diğer tarayıcı uygulamalarından nasıl farklı olacağı hakkında biraz ayrıntılı bilgi verilmektedir.

Web Push Protokolü ve Uç Noktaları

Push API standardının avantajı, uç noktayı alıp sunucunuza iletebilmeniz ve Web Push Protokolü'nü uygulayarak push mesajları gönderebilmenizdir.

Web Push Protokolü, push sağlayıcıların uygulayabileceği yeni bir standarttır. Bu standart, geliştiricilerin push sağlayıcının kim olduğu konusunda endişelenmelerine gerek kalmamasını sağlar. Buradaki amaç, FCM'de olduğu gibi API anahtarlarına kaydolup özel biçimlendirilmiş veriler gönderme ihtiyacını ortadan kaldırmaktır.

Chrome, Push API'yi uygulayan ilk tarayıcıydı ve FCM, Web Push Protokolü'nü desteklemez. Bu nedenle Chrome için gcm_sender_id gereklidir ve FCM için restful API'yi kullanmanız gerekir.

Chrome'un nihai hedefi, Chrome ve FCM ile Web Push Protokolü'nü kullanmaya geçmek.

O zamana kadar "https://fcm.googleapis.com/fcm/send" uç noktasını tespit edip diğer uç noktalardan ayrı olarak işleme almanız gerekir. Yani, yük verilerini belirli bir şekilde biçimlendirip yetkilendirme anahtarını eklemeniz gerekir.

Web Push Protokolü nasıl uygulanır?

Firefox Nightly şu anda push üzerinde çalışıyor ve muhtemelen Web Push Protokolü'nü uygulayan ilk tarayıcı olacak.

SSS

Özellikler nerede?

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

Web varlığımın birden fazla kaynağı varsa veya hem web hem de yerel varlığım varsa yinelenen bildirimleri engelleyebilir miyim?

Şu anda bu sorunun bir çözümü bulunmuyor ancak Chromium'da konuyla ilgili gelişmeleri takip edebilirsiniz.

İdeal senaryo, kullanıcının cihazı için bir tür kimlik kullanmak ve ardından sunucu tarafında yerel uygulama ile web uygulaması abonelik kimliklerini eşleştirip hangisine push mesajı gönderileceğine karar vermektir. Bunu ekran boyutu, cihaz modeli veya oluşturulan bir anahtarı web uygulaması ile yerel uygulama arasında paylaşarak yapabilirsiniz. Ancak her yaklaşımın avantajları ve dezavantajları vardır.

Neden gcm_sender_id kullanmam gerekiyor?

Bu, Chrome, Android için Opera ve Samsung Tarayıcı'nın Firebase Cloud Messaging (FCM) API'sini kullanabilmesi için gereklidir. Amaç, standart tamamlandığında ve FCM tarafından desteklendiğinde Web Push Protokolü'nü kullanmaktır.

Web soketlerini veya sunucudan gönderilen etkinlikleri (EventSource) neden kullanmıyorsunuz?

Push mesajlarının avantajı, sayfanız kapalı olsa bile hizmet çalışanınızın uyandırılıp bildirim gösterebilmesidir. Web soketlerinin ve EventSource'ın bağlantısı, sayfa veya tarayıcı kapatıldığında kapatılır.

Arka planda etkinlik yayınlamaya ihtiyacım yoksa ne yapmalıyım?

Arka planda yayınlamaya ihtiyacınız yoksa Web Soketleri mükemmel bir seçenektir.

Bildirim göstermeden push'i ne zaman kullanabilirim (ör. sessiz arka plan push'i)?

Bu özelliğin ne zaman kullanıma sunulacağı henüz belli değil ancak arka plan senkronizasyonunu uygulamak için bir plan var. Arka plan senkronizasyonuyla sessiz push'in etkinleştirilmesi konusunda henüz karar verilmedi veya spesifikasyon belirlenmedi ancak bu konu üzerinde tartışmalar devam ediyor.

Bu işlem için neden HTTPS gereklidir? Geliştirme sırasında bu sorunu nasıl çözebilirim?

Hizmet çalışanı komut dosyasının istenen kaynaktan geldiğinden ve ortadaki adam saldırısından kaynaklanmadığından emin olmak için hizmet çalışanlarının güvenli kaynaklara ihtiyacı vardır. Şu anda bu, canlı sitelerde HTTPS kullanılması anlamına geliyor. Ancak geliştirme sırasında localhost çalışacaktır.

Tarayıcı desteği nasıl görünür?

Chrome, kararlı sürümünde bu özelliği destekler. Mozilla, Firefox Nightly'de bu özelliğin üzerinde çalışmaktadır. Daha fazla bilgi için Push API'yi uygulama hatasına bakın ve bildirim uygulamalarını buradan takip edebilirsiniz.

Belirli bir süre geçtikten sonra bildirimleri kaldırabilir miyim?

Şu anda bu mümkün değildir ancak şu anda görünen bildirimlerin listesini alma desteğini eklemeyi planlıyoruz. Bildirim oluşturulduktan sonra bildirim için geçerlilik süresi ayarlamak istediğiniz bir kullanım alanı varsa lütfen yorum ekleyin. Yorumunuz Chrome ekibine iletilecektir.

Yalnızca belirli bir süre sonra kullanıcıya gönderilen bir push bildirimini durdurmanız gerekiyorsa ve bildirimin ne kadar süreyle görünür kalacağı önemli değilse FCM'nin "time to live" (ttl) parametresini kullanabilirsiniz. Daha fazla bilgi edinmek için buraya göz atın.

Chrome'daki push mesajlaşmanın sınırlamaları nelerdir?

Bu yayında belirtilen birkaç sınırlama vardır:

  • Chrome'un CCM'yi push hizmeti olarak kullanması, bir dizi özel şart oluşturur. Bu kısıtlamaların gelecekte kaldırılıp kaldırılamayacağını görmek için birlikte çalışıyoruz.
  • Push mesajı aldığınızda bildirim göstermeniz gerekir.
  • Masaüstünde Chrome'un çalışmadığı durumlarda push mesajlarının alınamaması, bu yöntemin dezavantajıdır. Bu durum, push mesajlarının her zaman alınacağı ChromeOS ve Android'den farklıdır.

Permissions API'yi kullanmamız gerekmez mi?

Permission API Chrome'da uygulanır ancak tüm tarayıcılarda kullanılamayabilir. Daha fazla bilgiyi buradan edinebilirsiniz.

Chrome, bir bildirimi tıkladığımda neden önceki sekmeyi açmıyor?

Bu sorun yalnızca şu anda bir hizmet çalışanı tarafından kontrol edilmeyen sayfaları etkiler. Buradan daha fazla bilgi edinebilirsiniz.

Kullanıcının cihazı push bildirimini aldığında bildirim güncel değilse ne olur?

Push mesajı aldığınızda her zaman bildirim göstermeniz gerekir. Bir bildirim göndermek istediğiniz ancak bildirimin yalnızca belirli bir süre boyunca yararlı olacağı senaryoda, CCM'de "time_to_live" parametresini kullanabilirsiniz. Böylece, FCM'nin süre sonu geçtiğinde push mesajını göndermemesi sağlanır.

Daha fazla bilgiyi burada bulabilirsiniz.

10 push mesajı gönderirsem ancak cihazın yalnızca bir tane almasını istersem ne olur?

FCM'de, aynı "collapse_key" değerine sahip bekleyen mesajları yeni mesajla değiştirmesini söylemek için kullanabileceğiniz bir "collapse_key" parametresi vardır.

Daha fazla bilgiyi burada bulabilirsiniz.