Pertama-tama, saya mohon maaf atas judul yang buruk itu, tetapi saya tidak bisa tidak.
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 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);
});
Sebelum ini, Anda harus menyimpan data di IndexDB atau menempatkan sesuatu di akhir URL ikon - eek.
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.
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();
}
Hal yang perlu diperhatikan 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 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. Di perangkat yang mendukung Vibration API - saat ini hanya Chrome untuk Android - Anda dapat 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, Anda tidak dapat melakukannya dan tidak ada 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. Namun, notifikasi ini digunakan di desktop untuk menampilkan notifikasi untuk aplikasi web yang mungkin saat ini Anda buka.
Satu-satunya alasan saya menyebutkannya adalah karena pada awalnya, deteksi fitur sederhana seperti di bawah akan membantu Anda mendukung desktop dan tidak menyebabkan error apa pun 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();
}