Memberi tahu Anda tentang Perubahan pada Notifikasi

Pertama, saya minta maaf atas judul yang buruk, tetapi saya tidak bisa.

Di Chrome 44, Notfication.data dan ServiceWorkerRegistration.getNotifications() ditambahkan dan membuka / menyederhanakan beberapa kasus penggunaan umum saat menangani notifikasi dengan pesan push.

Data Notifikasi

Notification.data memungkinkan Anda mengaitkan objek JavaScript dengan Notification.

Intisarinya adalah saat menerima pesan push, Anda dapat membuat notifikasi dengan beberapa data, lalu dalam peristiwa notificationclick, Anda bisa mendapatkan notifikasi yang diklik dan mendapatkan datanya.

Misalnya, membuat objek data dan menambahkannya ke opsi notifikasi Anda seperti berikut:

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';
    var data = {
    doge: {
        wow: 'such amaze notification data'
    }
    };

    event.waitUntil(
    self.registration.showNotification(title, {
        body: body,
        icon: icon,
        tag: tag,
        data: data
    })
    );
});

Berarti kita bisa mendapatkan informasi dalam peristiwa notificationclick:

self.addEventListener('notificationclick', function(event) {
    var doge = event.notification.data.doge;
    console.log(doge.wow);
});

Sebelumnya, Anda harus menyembunyikan data di IndexDB atau meletakkan sesuatu di akhir URL ikon - eek.

ServiceWorkerRegistration.getNotifications()

Salah satu permintaan umum dari developer yang menangani notifikasi push adalah agar memiliki kontrol yang lebih baik atas notifikasi yang ditampilkan.

Contoh kasus penggunaan adalah aplikasi chat saat pengguna mengirim beberapa pesan dan penerima menampilkan beberapa notifikasi. Idealnya, aplikasi web dapat melihat Anda memiliki beberapa notifikasi yang belum dilihat dan menciutkannya menjadi satu notifikasi.

Tanpa getNotifications(), hal terbaik yang dapat Anda lakukan adalah mengganti notifikasi sebelumnya dengan pesan terbaru. Dengan getNotifications(), Anda dapat "menciutkan" notifikasi jika notifikasi sudah ditampilkan, sehingga akan menghasilkan pengalaman pengguna yang jauh lebih baik.

Contoh mengelompokkan notifikasi bersama-sama.

Kode untuk melakukan hal ini relatif sederhana. Dalam peristiwa push Anda, panggil ServiceWorkerRegistration.getNotifications() untuk mendapatkan array Notifications saat ini, lalu tentukan perilaku yang tepat, baik itu menciutkan semua notifikasi maupun dengan menggunakan Notification.tag.

function showNotification(title, body, icon, data) {
    var notificationOptions = {
    body: body,
    icon: icon ? icon : 'images/touch/chrome-touch-icon-192x192.png',
    tag: 'simple-push-demo-notification',
    data: data
    };

    self.registration.showNotification(title, notificationOptions);
    return;
}

self.addEventListener('push', function(event) {
    console.log('Received a push message', event);

    // Since this is no payload data with the first version
    // of Push notifications, here we'll grab some data from
    // an API and use it to populate a notification
    event.waitUntil(
    fetch(API_ENDPOINT).then(function(response) {
        if (response.status !== 200) {
        console.log('Looks like there was a problem. Status Code: ' +
            response.status);
        // Throw an error so the promise is rejected and catch() is executed
        throw new Error();
        }

        // Examine the text in the response
        return response.json().then(function(data) {
        var title = 'You have a new message';
        var message = data.message;
        var icon = 'images/notification-icon.png';
        var notificationTag = 'chat-message';

        var notificationFilter = {
            tag: notificationTag
        };
        return self.registration.getNotifications(notificationFilter)
            .then(function(notifications) {
            if (notifications && notifications.length > 0) {
                // Start with one to account for the new notification
                // we are adding
                var notificationCount = 1;
                for (var i = 0; i < notifications.length; i++) {
                var existingNotification = notifications[i];
                if (existingNotification.data &&
                    existingNotification.data.notificationCount) {
                    notificationCount +=
existingNotification.data.notificationCount;
                } else {
                    notificationCount++;
                }
                existingNotification.close();
                }
                message = 'You have ' + notificationCount +
                ' weather updates.';
                notificationData.notificationCount = notificationCount;
            }

            return showNotification(title, message, icon, notificationData);
            });
        });
    }).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';

        return showNotification(title, message);
    })
    );
});

self.addEventListener('notificationclick', function(event) {
    console.log('On notification click: ', event);

    if (Notification.prototype.hasOwnProperty('data')) {
    console.log('Using Data');
    var url = event.notification.data.url;
    event.waitUntil(clients.openWindow(url));
    } else {
    event.waitUntil(getIdb().get(KEY_VALUE_STORE_NAME,
event.notification.tag).then(function(url) {
        // At the moment you cannot open third party URL's, a simple trick
        // is to redirect to the desired URL from a URL on your domain
        var redirectUrl = '/redirect.html?redirect=' +
        url;
        return clients.openWindow(redirectUrl);
    }));
    }
});

Hal pertama yang harus disoroti dengan cuplikan kode ini adalah kita memfilter notifikasi dengan meneruskan objek filter ke getNotifications(). Ini berarti kita bisa mendapatkan daftar notifikasi untuk tag tertentu (dalam contoh ini untuk percakapan tertentu).

var notificationFilter = {
    tag: notificationTag
};
return self.registration.getNotifications(notificationFilter)

Kemudian, kami memeriksa notifikasi yang terlihat dan memeriksa apakah ada jumlah notifikasi yang terkait dengan notifikasi tersebut dan penambahannya berdasarkan itu. Dengan cara ini, jika ada satu notifikasi yang memberi tahu pengguna bahwa ada dua pesan yang belum dibaca, kita ingin menunjukkan bahwa ada tiga pesan yang belum dibaca ketika push baru masuk.

var notificationCount = 1;
for (var i = 0; i < notifications.length; i++) {
    var existingNotification = notifications[i];
    if (existingNotification.data && existingNotification.data.notificationCount) {
    notificationCount += existingNotification.data.notificationCount;
    } else {
    notificationCount++;
    }
    existingNotification.close();
}

Detail yang perlu disoroti adalah Anda perlu memanggil close() pada notifikasi untuk memastikan notifikasi dihapus dari daftar notifikasi. Ini adalah bug di Chrome karena setiap notifikasi diganti dengan notifikasi berikutnya karena tag yang sama digunakan. Saat ini, penggantian ini tidak tercermin dalam array yang ditampilkan dari getNotifications().

Ini hanyalah salah satu contoh getNotifications() dan seperti yang dapat Anda bayangkan, API ini membuka berbagai kasus penggunaan lainnya.

NotificationOptions.vibrate

Mulai Chrome 45, Anda dapat menentukan pola getaran saat membuat notifikasi. Pada perangkat yang mendukung Vibration API - saat ini hanya Chrome untuk Android - ini memungkinkan Anda menyesuaikan pola getaran yang akan digunakan saat notifikasi ditampilkan.

Pola getaran dapat berupa array angka, atau angka tunggal yang diperlakukan sebagai array dari satu angka. Nilai dalam array mewakili waktu dalam milidetik, dengan indeks genap (0, 2, 4, ...) menunjukkan durasi getaran, dan indeks ganjil menunjukkan durasi jeda sebelum getaran berikutnya.

self.registration.showNotification('Buzz!', {
    body: 'Bzzz bzzzz',
    vibrate: [300, 100, 400] // Vibrate 300ms, pause 100ms, then vibrate 400ms
});

Permintaan Fitur Umum Lainnya

Satu-satunya permintaan fitur umum yang tersisa dari developer adalah kemampuan untuk menutup notifikasi setelah jangka waktu tertentu atau kemampuan untuk mengirim notifikasi push dengan tujuan hanya menutup notifikasi jika terlihat.

Saat ini, belum ada cara untuk melakukan ini dan tidak ada apa pun dalam spesifikasi yang akan mengizinkannya :( namun tim engineer Chrome mengetahui kasus penggunaan ini.

Notifikasi Android

Di desktop, Anda dapat membuat notifikasi dengan kode berikut:

new Notification('Hello', {body: 'Yay!'});

Metode ini tidak pernah didukung pada Android karena pembatasan platform: khususnya, Chrome tidak dapat mendukung callback pada objek Notifikasi, seperti onclick. Tapi alat ini digunakan di desktop untuk menampilkan notifikasi untuk aplikasi web yang mungkin saat ini Anda buka.

Satu-satunya alasan saya menyebutkannya adalah, pada awalnya, deteksi fitur sederhana seperti di bawah ini akan membantu Anda mendukung desktop dan tidak menyebabkan error di Android:

if (!'Notification' in window) {
    // Notifications aren't supported
    return;
}

Namun, dengan dukungan notifikasi push yang sekarang ada di Chrome untuk Android, notifikasi dapat dibuat dari ServiceWorker, tetapi tidak dari halaman web, yang berarti deteksi fitur ini tidak lagi sesuai. Jika Anda mencoba membuat notifikasi di Chrome untuk Android, Anda akan menerima pesan error ini:

_Uncaught TypeError: Failed to construct 'Notification': Illegal constructor.
Use ServiceWorkerRegistration.showNotification() instead_

Cara terbaik untuk mendeteksi fitur untuk Android dan desktop saat ini adalah dengan melakukan hal berikut:

    function isNewNotificationSupported() {
        if (!window.Notification || !Notification.requestPermission)
            return false;
        if (Notification.permission == 'granted')
            throw new Error('You must only call this \*before\* calling
    Notification.requestPermission(), otherwise this feature detect would bug the
    user with an actual notification!');
        try {
            new Notification('');
        } catch (e) {
            if (e.name == 'TypeError')
                return false;
        }
        return true;
    }

Ini dapat digunakan seperti berikut:

    if (window.Notification && Notification.permission == 'granted') {
        // We would only have prompted the user for permission if new
        // Notification was supported (see below), so assume it is supported.
        doStuffThatUsesNewNotification();
    } else if (isNewNotificationSupported()) {
        // new Notification is supported, so prompt the user for permission.
        showOptInUIForNotifications();
    }