Push-уведомления

Урок даёт обзор push-уведомлений в PWA: как запросить разрешение, подписаться и показать уведомление.

Push-уведомление — сообщение, которое сервер присылает приложению, даже когда оно закрыто; Service Worker получает его и показывает системное уведомление.

Два разных API

Push в PWA — это связка двух API, которые часто путают:

  • Notification API — показывает уведомление (всплывашку) пользователю. Может работать и без сервера.
  • Push API — позволяет серверу доставить сообщение в Service Worker через push-сервис браузера, даже когда вкладка закрыта.

Полноценный push = сервер шлёт через Push API → Service Worker ловит событие push → показывает уведомление через Notification API.

Шаг 1: разрешение

Уведомления нельзя слать без согласия пользователя. Сначала запрашиваем разрешение:

const permission = await Notification.requestPermission();
if (permission === 'granted') {
  // можно показывать уведомления
}

Просить разрешение лучше не на входе, а после понятного пользователю действия — иначе высок процент отказов, а повторно спросить уже нельзя.

Шаг 2: подписка

Чтобы сервер мог слать push, приложение подписывается через PushManager, получая объект подписки с уникальным эндпоинтом. Его отправляют на сервер и хранят.

const reg = await navigator.serviceWorker.ready;
const subscription = await reg.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: vapidPublicKey  // ключ VAPID
});
// отправляем subscription на свой сервер

Ключи VAPID идентифицируют ваш сервер для push-сервиса. Флаг userVisibleOnly: true обязателен: он обещает, что каждый push покажет видимое уведомление (нельзя слать «тихие» push для слежки).

Шаг 3: показ в Service Worker

self.addEventListener('push', function (event) {
  const data = event.data ? event.data.json() : {};
  event.waitUntil(
    self.registration.showNotification(data.title || 'Уведомление', {
      body: data.body,
      icon: '/icons/icon-192.png'
    })
  );
});

Как работает под капотом доставка push

Между вашим сервером и устройством стоит push-сервис браузера (у Chrome, Firefox, Safari — свои). Ваш сервер шлёт сообщение не напрямую устройству, а push-сервису, на эндпоинт из подписки. Push-сервис доставляет его на устройство и будит Service Worker событием push — даже если приложение закрыто. Поэтому push работает «в фоне»: устройство держит соединение с push-сервисом, а не с вашим сервером.

Ваш сервер --> push-сервис браузера --> устройство --> SW (событие push) --> уведомление

Частые ошибки

  • Просить разрешение на входе. Массовые отказы; повторно спросить нельзя.
  • Забыть userVisibleOnly. Подписка не оформится в Chrome.
  • Не обрабатывать клик по уведомлению. Добавьте обработчик notificationclick, чтобы открыть нужную страницу.
  • Слать слишком много push. Пользователь отключит уведомления или удалит приложение.

Итоги

  • Push = Push API (доставка) + Notification API (показ).
  • Сначала разрешение (Notification.requestPermission), потом подписка (pushManager.subscribe).
  • Сообщение идёт через push-сервис браузера и будит Service Worker событием push.
  • userVisibleOnly: true обязателен; разрешение просите после понятного действия.
Проверьте себя
1. В чём разница между Push API и Notification API?
AЭто одно и то же
BPush API доставляет сообщение от сервера в Service Worker, а Notification API показывает уведомление пользователю
CPush API только для iOS
DNotification API работает только онлайн
2. Через что проходит push-сообщение по пути от вашего сервера к устройству?
AНапрямую от сервера к устройству
BЧерез push-сервис браузера, который доставляет сообщение и будит Service Worker
CЧерез манифест
DЧерез localStorage
3. Когда лучше запрашивать разрешение на уведомления?
AСразу при входе на сайт
BПосле понятного пользователю действия, чтобы снизить долю отказов
CНикогда не спрашивать
DТолько после установки приложения