К этому моменту мы рассмотрели подписку пользователя и отправку push-сообщения. Следующий шаг — получить это push-сообщение на устройстве пользователя и отобразить уведомление (а также выполнить любую другую работу, которую мы можем захотеть выполнить).
Push-событие
Когда сообщение будет получено, в вашем сервис-воркере будет отправлено событие push.
Код для настройки прослушивателя push-событий должен быть очень похож на любой другой прослушиватель событий, который вы пишете на JavaScript:
self.addEventListener('push', function(event) {
if (event.data) {
console.log('This push event has data: ', event.data.text());
} else {
console.log('This push event has no data.');
}
});
Самая странная часть этого кода для большинства разработчиков, которые плохо знакомы с сервис-воркерами, — это переменная self
. self
обычно используется в Web Workers, которыми является сервисный работник. self
относится к глобальной области действия, что-то вроде window
на веб-странице. Но для веб-работников и сервис-работников self
относится к самому работнику.
В приведенном выше примере self.addEventListener()
можно рассматривать как добавление прослушивателя событий к самому сервисному работнику.
В примере события push мы проверяем, есть ли какие-либо данные, и выводим что-то на консоль.
Существуют и другие способы анализа данных из события push:
// Returns string
event.data.text()
// Parses data as JSON string and returns an Object
event.data.json()
// Returns blob of data
event.data.blob()
// Returns an arrayBuffer
event.data.arrayBuffer()
Большинство людей используют json()
или text()
в зависимости от того, чего они ожидают от своего приложения.
В этом примере показано, как добавить прослушиватель push-событий и как получить доступ к данным, но в нем отсутствуют две очень важные функции. Он не показывает уведомление и не использует event.waitUntil()
.
Подождите, пока
Одна из вещей, которую следует понимать в отношении сервис-воркеров, заключается в том, что у вас мало контроля над тем, когда код сервис-воркера будет запускаться. Браузер решает, когда его активировать, а когда завершить. Единственный способ сказать браузеру: «Эй, я очень занят важными делами» — это передать обещание в метод event.waitUntil()
. При этом браузер будет поддерживать работу сервис-воркера до тех пор, пока переданное вами обещание не будет выполнено.
При использовании push-событий существует дополнительное требование: вы должны отобразить уведомление до того, как переданное вами обещание будет выполнено.
Вот базовый пример отображения уведомления:
self.addEventListener('push', function(event) {
const promiseChain = self.registration.showNotification('Hello, World.');
event.waitUntil(promiseChain);
});
Вызов self.registration.showNotification()
— это метод, который отображает уведомление пользователю и возвращает обещание, которое будет выполнено после отображения уведомления.
Чтобы сделать этот пример максимально понятным, я присвоил это обещание переменной с именем promiseChain
. Затем это передается в event.waitUntil()
. Я знаю, что это очень многословно, но я видел ряд проблем, которые возникли в результате неправильного понимания того, что должно быть передано в waitUntil()
, или в результате разрыва цепочки обещаний.
Более сложный пример с сетевым запросом данных и отслеживанием push-события с помощью аналитики может выглядеть так:
self.addEventListener('push', function(event) {
const analyticsPromise = pushReceivedTracking();
const pushInfoPromise = fetch('/api/get-more-data')
.then(function(response) {
return response.json();
})
.then(function(response) {
const title = response.data.userName + ' says...';
const message = response.data.message;
return self.registration.showNotification(title, {
body: message
});
});
const promiseChain = Promise.all([
analyticsPromise,
pushInfoPromise
]);
event.waitUntil(promiseChain);
});
Здесь мы вызываем функцию, которая возвращает обещание pushReceivedTracking()
, которое, ради примера, мы можем представить, что оно отправит сетевой запрос нашему поставщику аналитики. Мы также делаем сетевой запрос, получаем ответ и показываем уведомление, используя данные ответов для заголовка и сообщения уведомления.
Мы можем гарантировать, что сервис-воркер будет оставаться активным, пока выполняются обе эти задачи, объединив эти обещания с Promise.all()
. Полученное обещание передается в event.waitUntil()
, что означает, что браузер будет ждать завершения обоих обещаний, прежде чем проверять, что уведомление было отображено, и завершать работу сервис-воркера.
Причина, по которой нам следует беспокоиться о waitUntil()
и о том, как ее использовать, заключается в том, что одна из наиболее распространенных проблем, с которыми сталкиваются разработчики, заключается в том, что, когда цепочка обещаний неверна или нарушена, Chrome отображает это уведомление «по умолчанию»:
Chrome будет отображать только сообщение «Этот сайт был обновлен в фоновом режиме». уведомление, когда получено push-сообщение, а событие push в сервисном работнике не отображает уведомление после завершения обещания, переданного в event.waitUntil()
.
Основная причина, по которой разработчики на это попадаются, заключается в том, что их код часто вызывает self.registration.showNotification()
, но они ничего не делают с возвращаемым обещанием. Периодически это приводит к отображению уведомления по умолчанию. Например, мы могли бы удалить возврат self.registration.showNotification()
в приведенном выше примере, и мы рискуем увидеть это уведомление.
self.addEventListener('push', function(event) {
const analyticsPromise = pushReceivedTracking();
const pushInfoPromise = fetch('/api/get-more-data')
.then(function(response) {
return response.json();
})
.then(function(response) {
const title = response.data.userName + ' says...';
const message = response.data.message;
self.registration.showNotification(title, {
body: message
});
});
const promiseChain = Promise.all([
analyticsPromise,
pushInfoPromise
]);
event.waitUntil(promiseChain);
});
Вы видите, как легко это пропустить.
Просто помните: если вы видите это уведомление, проверьте свои цепочки обещаний и event.waitUntil()
.
В следующем разделе мы рассмотрим, что мы можем сделать для стилизации уведомлений и какой контент мы можем отображать.
Куда идти дальше
- Обзор веб-push-уведомлений
- Как работает Push
- Подписка пользователя
- Разрешение UX
- Отправка сообщений с помощью библиотек Web Push
- Веб-пуш-протокол
- Обработка push-событий
- Отображение уведомления
- Поведение уведомлений
- Общие шаблоны уведомлений
- Часто задаваемые вопросы по push-уведомлениям
- Распространенные проблемы и сообщения об ошибках