Memberi tahu Anda tentang Perubahan pada Notifikasi

Pertama-tama, saya mohon maaf atas judul yang buruk itu, tetapi saya tidak bisa tidak.

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

Data Notifikasi

Notification.data memungkinkan Anda mengaitkan objek JavaScript dengan Pemberitahuan.

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

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

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

Artinya, 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 menyimpan data di IndexDB atau meletakkan sesuatu di akhir URL ikon, misalnya.

ServiceWorkerRegistration.getNotifications()

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

Contoh kasus penggunaan adalah aplikasi chat tempat pengguna mengirim beberapa pesan dan penerima menampilkan beberapa notifikasi. Idealnya, aplikasi web akan dapat melihat bahwa 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 memberikan pengalaman pengguna yang jauh lebih baik.

Contoh pengelompokan notifikasi.

Kode untuk melakukannya relatif sederhana. Di dalam peristiwa push, panggil ServiceWorkerRegistration.getNotifications() untuk mendapatkan array Notifikasi saat ini, lalu dari sana tentukan perilaku yang tepat, baik itu menyempitkan semua notifikasi atau 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 perlu disoroti dengan cuplikan kode ini adalah kita memfilter notifikasi dengan meneruskan objek filter ke getNotifications(). Artinya, kita dapat mendapatkan daftar notifikasi untuk tag tertentu (dalam contoh ini untuk percakapan tertentu).

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

Kemudian, kita akan melihat notifikasi yang terlihat dan memeriksa apakah ada jumlah notifikasi yang terkait dengan notifikasi tersebut dan menambahkannya berdasarkan hal 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 saat push baru tiba.

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

Halus 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 Getaran API - saat ini hanya Chrome untuk Android - hal ini memungkinkan Anda menyesuaikan pola getaran yang akan digunakan saat notifikasi ditampilkan.

Pola getaran dapat berupa array angka, atau satu angka yang diperlakukan sebagai array dari satu angka. Nilai dalam array mewakili waktu dalam milidetik, dengan indeks genap (0, 2, 4, ...) adalah durasi getaran, dan indeks ganjil adalah 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 yang Tersisa

Satu 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 tidak ada cara untuk melakukan hal ini dan tidak ada apa pun dalam spesifikasi yang akan mengizinkannya :( tetapi tim engineer Chrome mengetahui kasus penggunaan ini.

Notifikasi Android

Di desktop, Anda dapat membuat notifikasi dengan kode berikut:

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

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

Satu-satunya alasan saya menyebutkannya adalah bahwa 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 kini tersedia 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_

Saat ini, cara terbaik untuk mendeteksi fitur untuk Android dan desktop 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();
    }