Codelab: создание клиента push-уведомлений

Кейт Джеффрис
Kate Jeffreys

В этой кодовой лаборатории шаг за шагом показано, как создать клиент push-уведомлений. К концу работы над кодом у вас будет клиент, который:

  • Подписывает пользователя на push-уведомления.
  • Получает push-сообщения и отображает их в виде уведомлений.
  • Отписывает пользователя от push-уведомлений.

Цель этой лаборатории кода – помочь вам учиться на практике, и в ней мало говорится о концепциях. Узнайте , как работают push-уведомления? узнать о концепциях push-уведомлений.

Серверный код этой лаборатории уже готов. В этой лаборатории кода вы будете реализовывать только клиент. Чтобы узнать, как реализовать сервер push-уведомлений, ознакомьтесь с Codelab: Создание сервера push-уведомлений .

Ознакомьтесь с push-notifications-client-codelab-complete ( source ), чтобы увидеть полный код.

Совместимость с браузером

Известно, что эта кодовая лаборатория работает со следующими комбинациями операционной системы и браузера:

  • Windows: Chrome, Edge
  • macOS: Chrome, Firefox
  • Андроид: Хром, Фаерфокс.

Известно, что эта кодовая лаборатория не работает со следующими операционными системами (или комбинациями операционной системы и браузера):

  • macOS: Brave, Edge, Safari
  • iOS

Настраивать

Получите редактируемую копию кода

Редактор кода, который вы видите справа от этих инструкций, в этой лаборатории кода будет называться Glitch UI .

  1. Нажмите Remix to Edit, чтобы сделать проект доступным для редактирования.

Настройка аутентификации

Прежде чем вы сможете заставить работать push-уведомления, вам необходимо настроить на сервере и клиенте ключи аутентификации. См. раздел Подписание запросов протокола веб-push, чтобы узнать, почему.

  1. В пользовательском интерфейсе Glitch нажмите «Инструменты» , а затем нажмите «Терминал» , чтобы открыть терминал Glitch.
  2. В терминале Glitch запустите npx web-push generate-vapid-keys . Скопируйте значения закрытого и открытого ключей.
  3. В пользовательском интерфейсе Glitch откройте .env и обновите VAPID_PUBLIC_KEY и VAPID_PRIVATE_KEY . Установите для VAPID_SUBJECT mailto:test@test.test . Все эти значения должны быть заключены в двойные кавычки. После внесения обновлений ваш файл .env должен выглядеть примерно так:
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. Закройте терминал Glitch.
  1. Откройте public/index.js .
  2. Замените VAPID_PUBLIC_KEY_VALUE_HERE значением вашего открытого ключа.

Зарегистрируйте сервисного работника

Вашему клиенту в конечном итоге понадобится сервисный работник для получения и отображения уведомлений. Лучше всего зарегистрировать сервисного работника как можно раньше. Дополнительную информацию см. в разделе Получение и отображение отправленных сообщений в виде уведомлений .

  1. Замените комментарий // TODO add startup logic here следующим кодом:
// TODO add startup logic here
if ('serviceWorker' in navigator && 'PushManager' in window) {
  navigator.serviceWorker.register('./service-worker.js').then(serviceWorkerRegistration => {
    console.info('Service worker was registered.');
    console.info({serviceWorkerRegistration});
  }).catch(error => {
    console.error('An error occurred while registering the service worker.');
    console.error(error);
  });
  subscribeButton.disabled = false;
} else {
  console.error('Browser does not support service workers or push messages.');
}

subscribeButton.addEventListener('click', subscribeButtonHandler);
unsubscribeButton.addEventListener('click', unsubscribeButtonHandler);
  1. Чтобы просмотреть сайт, нажмите «Просмотреть приложение» . Затем нажмите Полноэкранный режим полноэкранный .
  1. Нажмите «Control+Shift+J» (или «Command+Option+J» на Mac), чтобы открыть DevTools.
  2. Откройте вкладку Консоль . Вы должны увидеть сообщение Service worker was registered. вошел в консоль.

Запросить разрешение на push-уведомления

Никогда не следует запрашивать разрешение на отправку push-уведомлений при загрузке страницы. Вместо этого ваш пользовательский интерфейс должен спрашивать пользователя, хотят ли они получать push-уведомления. Как только они явным образом подтвердят (например, нажатием кнопки), вы сможете начать формальный процесс получения разрешения на push-уведомление из браузера.

  1. В пользовательском интерфейсе Glitch нажмите «Просмотреть исходный код» , чтобы вернуться к коду.
  2. В public/index.js замените комментарий // TODO в subscribeButtonHandler() следующим кодом:
// TODO
// Prevent the user from clicking the subscribe button multiple times.
subscribeButton.disabled = true;
const result = await Notification.requestPermission();
if (result === 'denied') {
  console.error('The user explicitly denied the permission request.');
  return;
}
if (result === 'granted') {
  console.info('The user accepted the permission request.');
}
  1. Вернитесь на вкладку приложения и нажмите «Подписаться», чтобы отправить рассылку . Ваш браузер или операционная система, вероятно, спросят вас, хотите ли вы, чтобы веб-сайт отправлял вам push-уведомления. Нажмите «Разрешить» (или любую аналогичную фразу, которую использует ваш браузер/ОС). В консоли вы должны увидеть сообщение о том, был ли запрос принят или отклонен.

Подпишитесь на push-уведомления

Процесс подписки включает в себя взаимодействие с веб-службой, контролируемой поставщиком браузера, которая называется push-службой . Как только вы получите информацию о подписке на push-уведомления, вам необходимо отправить ее на сервер, и сервер сохранит ее в базе данных на длительный срок. Дополнительную информацию о процессе подписки см. в разделе Подписка клиента на push-уведомления .

  1. Добавьте следующий выделенный код в subscribeButtonHandler() :
subscribeButton.disabled = true;
const result = await Notification.requestPermission();
if (result === 'denied') {
  console.error('The user explicitly denied the permission request.');
  return;
}
if (result === 'granted') {
  console.info('The user accepted the permission request.');
}
const registration = await navigator.serviceWorker.getRegistration();
const subscribed = await registration.pushManager.getSubscription();
if (subscribed) {
  console.info('User is already subscribed.');
  notifyMeButton.disabled = false;
  unsubscribeButton.disabled = false;
  return;
}
const subscription = await registration.pushManager.subscribe({
  userVisibleOnly: true,
  applicationServerKey: urlB64ToUint8Array(VAPID_PUBLIC_KEY)
});
notifyMeButton.disabled = false;
fetch('/add-subscription', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(subscription)
});

Параметр userVisibleOnly должен иметь true . Возможно, однажды станет возможным отправлять сообщения без отображения видимых для пользователя уведомлений ( тихие нажатия ), но браузеры в настоящее время не поддерживают такую ​​возможность из соображений конфиденциальности.

Значение applicationServerKey зависит от служебной функции, которая преобразует строку base64 в Uint8Array. Это значение используется для аутентификации между вашим сервером и службой push-уведомлений.

Отписаться от push-уведомлений

После того как пользователь подписался на push-уведомления, ваш пользовательский интерфейс должен предоставить возможность отказаться от подписки на случай, если пользователь передумает и больше не захочет получать push-уведомления.

  1. Замените комментарий // TODO в unsubscribeButtonHandler() следующим кодом:
// TODO
const registration = await navigator.serviceWorker.getRegistration();
const subscription = await registration.pushManager.getSubscription();
fetch('/remove-subscription', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({endpoint: subscription.endpoint})
});
const unsubscribed = await subscription.unsubscribe();
if (unsubscribed) {
  console.info('Successfully unsubscribed from push notifications.');
  unsubscribeButton.disabled = true;
  subscribeButton.disabled = false;
  notifyMeButton.disabled = true;
}

Получите push-сообщение и отобразите его как уведомление.

Как упоминалось ранее, вам нужен сервис-воркер, который будет обрабатывать получение и отображение сообщений, отправленных клиенту с вашего сервера. Дополнительные сведения см. в разделе Получение и отображение отправленных сообщений в виде уведомлений .

  1. Откройте файл public/service-worker.js и замените комментарий // TODO в обработчике push событий сервис-воркера следующим кодом:
// TODO
let data = event.data.json();
const image = 'https://cdn.glitch.com/614286c9-b4fc-4303-a6a9-a4cef0601b74%2Flogo.png?v=1605150951230';
const options = {
  body: data.options.body,
  icon: image
}
self.registration.showNotification(
  data.title, 
  options
);
  1. Вернитесь на вкладку приложения.
  2. Нажмите «Уведомить меня» . Вы должны получить push-уведомление.
  3. Попробуйте открыть URL-адрес вкладки вашего приложения в других браузерах (или даже на других устройствах), пройти рабочий процесс подписки, а затем нажать «Уведомить всех» . Вы должны получить одно и то же push-уведомление во всех браузерах, на которые вы подписались. Вернитесь к разделу «Совместимость браузера», чтобы просмотреть список комбинаций браузера и ОС, которые, как известно, работают или не работают.

Вы можете настроить уведомление разными способами. Дополнительные сведения см. в параметрах ServiceWorkerRegistration.showNotification() .

Открытие URL-адреса, когда пользователь нажимает уведомление

В реальном мире вы, вероятно, будете использовать уведомление как способ повторно привлечь пользователя и побудить его посетить ваш сайт. Для этого вам нужно немного больше настроить вашего сервисного работника.

  1. Замените комментарий // TODO в обработчике события notificationclick сервис-воркера следующим кодом:
// TODO
event.notification.close();
event.waitUntil(self.clients.openWindow('https://web.dev'));
  1. Вернитесь на вкладку приложения, отправьте себе еще одно уведомление, а затем щелкните уведомление. Ваш браузер должен открыть новую вкладку и загрузить https://web.dev .

Следующие шаги