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 bazı özelliklerini ve Service Worker'ların çevrimdışı becerilerini 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 nelerin ekleneceğini göreceğiz. Son olarak, bir SSS bölümümüz olacak.

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ını uygulayacak bir Service Worker'a sahip olma bağımlılığı 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şleyici, kullanıcının push mesajları için abone olmasını veya e-posta listesinden çıkmasını sağlar. isPushEnabled, push mesajlarının şu anda abone olup olmadığını izleyen genel bir değişkendir. Bunlara kod snippet'lerinde başvurulur.

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 sitemizde hizmet çalışanı olduğunu söyleyeceğiz.

İ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, yukarıda initialiseState() yönteminde 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.

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şturun

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 ve projeyi oluşturun. Proje kontrol paneline yönlendirilirsiniz:

Firebase Projesi Ana Sayfası

Bu kontrol panelinde sol üst köşede bulunan proje adının yanındaki dişliyi 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ı API anahtarı ve sonraki bölümde web uygulaması manifest dosyasına eklememiz gereken gönderen kimliği yer alır.

Web uygulaması manifesti ekleyin

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 çok 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şlemle, kullanıcıdan push bildirimleri göndermesi için kaynağınıza izin vermesi istenir. 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 push etkinliği işleyici eklenene kadar hiçbir şey olmayacaktır.

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 vadet gerektirir ve bir etkinlik işleyicinin ömrünü uzatır (veya hizmet çalışanını hayatta tutma olarak düşünülebilir), vaat gerçekleşene kadar uzatılır. Bu durumda event.waitUntil öğesine iletilen taahhüt, showNotification() tarafından döndürülen Vaat olur.

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 push mesajı gönderirken bu bildirimin gösterilip gösterilmeyeceğini görelim.

Push mesajı gönderme

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

Bu yalnızca FCM'yi 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 vardır.

Ö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 şöyle olacak:

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ırsınız ve bu uç noktayı standart bir şekilde çağırırsınız. Uç nokta, 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 işlem 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 belgeleri 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 push mesajı örneği.

Arka uç mantığınızı geliştirirken POST gövdesinin Yetkilendirme başlığının ve biçiminin FCM uç noktasına özgü olduğunu unutmayın. Bu nedenle, uç noktanın FCM için olduğunu tespit edin ve başlığı koşullu olarak ekleyip POST gövdesini biçimlendirin. Diğer tarayıcılar için (ve gelecekte Chrome'da) Web Push Protokolü'nü uygulamanız gerekecektir.

Push API'sinin Chrome'daki 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 desteklenmediğinden, bir bildirimi doldurmak için gereken bilgileri almak amacıyla getirme işlemi gerçekleştirmeniz gerekir.

Daha Eksiksiz Bir Push Etkinliği Örneği

Şu ana kadar gördüğümüz bildirim oldukça basit ve örneklere bakıldığında gerçek dünyadaki kullanım alanını kapsama konusunda oldukça kötü.

Gerçekçi bir şekilde, çoğu kişi bildirimi görüntülemeden önce sunucularından bazı bilgileri almak ister. Bu, bildirim başlığını ve mesajı belirli bir şeyle doldurmaya veya bir adım daha ileri gidip bazı sayfaları ya da verileri önbelleğe almaya yarayan veriler olabilir. Böylece, kullanıcı bildirimi tıkladığında tarayıcı açıldığında her şey anında kullanılabilir (ağ o anda kullanılabilir durumda olmasa bile).

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() işlevinin bir promise aldığını ve bunun sonucunda showNotification() işlevinin promise döndürdüğünü bir kez daha vurgulamak isteriz. Diğer bir deyişle, asenkron fetch() çağrısı tamamlanana ve bildirim gösterilene kadar etkinlik işleyicimiz 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ıza 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 aboneliğini iptal etme

Bir kullanıcının cihazına abone oldunuz ve bu kullanıcı push mesajları alıyor. Peki bu 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 sunucuyla 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. Çözümlerden biri, sunucunuzun en son ayrıntılara ihtiyaç duyup duymadığını belirlemek için çerezdeki endpoint durumunu izlemektir.

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 (push mesajlarını tetiklemek için standart bir API gibi) mevcuttur, ancak bu sürüm, web uygulamalarınıza hemen push mesajları oluşturmaya 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 Geliştirici Araçları kullanılarak hata ayıklama yapılabilir. Hizmet çalışanıyla ilgili sorunları 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, halihazırda çalışan hizmet çalışanları dışında çok fazla bilgi sağlamaz.
  2. chrome://serviceworker-internals adresine gidin. Buradan Service Worker'ların durumunu ve varsa hataları görebilirsiniz. DevTools'ta benzer bir özellik grubu bulunana kadar bu sayfa geçicidir.

Service Worker'larda yeni olan herkese verebileceğim en iyi ipuçlarından biri, "Geliştirici Araçları penceresini aç ve hata ayıklama için Service Worker başlangıcında JavaScript yürütmesini duraklat" 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 varsa 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 bu, FCM kayıt kimliğinde bir sorun olduğunu ve push mesajının Chrome'a gönderilmediğini gösterir.

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 gitmeniz, cihazınızı bulmanız ve hizmet çalışanınızın URL'sini içeren "Worker pid:...." adlı bir liste öğesi bulmanı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 bildirimleriyle ilgili kullanıcı deneyimiyle ilgili en iyi uygulamaların yanı sıra push bildirimleriyle çalışırken karşılaşılan bazı nadir durumları kapsayan bir belge hazırlamaktadır.

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

Bu bölümde, bu uygulamanın bilmeniz gereken Chrome'a özgü bazı bölümleri ve diğer tarayıcı uygulamalarından nasıl farklılık gösterebileceği ile ilgili biraz ayrıntıya giriyoruz.

Web Push Protokolü ve Uç Noktaları

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

Web Push Protokolü, aktarma sağlayıcılarının uygulayabileceği yeni bir standarttır ve geliştiricilerin push sağlayıcının kim olduğu konusunda endişe duymalarına gerek kalmaz. Ana fikir, bu sayede API anahtarlarına kaydolma ve FCM'de olduğu gibi özel olarak biçimlendirilmiş veriler gönderme zorunluluğunu ortadan kaldırı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'de hem de yerel varlığım varsa yinelenen bildirimleri önleyebilir 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, oluşturulan bir anahtarı web uygulaması ve yerel uygulama arasında paylaşarak yapabilirsiniz, ancak her yaklaşımın artıları ve eksileri vardır.

gcm_sender_id neden gerekli?

Bu, Chrome, Android için Opera ve Samsung Tarayıcı'nın Firebase Cloud Messaging (FCM) API'yi kullanabilmesi için gereklidir. Amaç, standart tamamlandığında ve FCM bunu desteklediğ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?

Service Worker'lar, Service Worker komut dosyasının hedeflenen kaynaktan geldiğinden ve ortadaki adam saldırısından kaynaklanmadığından emin olmak için güvenli kaynaklara ihtiyaç duyar. Ş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ğil ancak gösterilen bildirimlerin listesini almak için destek 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?

İzin API'si Chrome'da uygulanmış olsa da 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 yalnızca belirli bir süre boyunca yararlı olan bir 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.