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

Кейт Джеффрис
Kate Jeffreys
Кейс Баскс
Kayce Basques

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

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

Эта практическая работа направлена ​​на обучение на практике и не слишком подробно рассматривает концепции. Ознакомьтесь с разделом «Как работают push-уведомления», чтобы узнать о концепциях push-уведомлений.

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

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

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

  • Windows: Chrome, Edge
  • macOS: Chrome, Firefox
  • Android: Chrome, Firefox

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

  • macOS: Brave, Edge, Safari
  • iOS

Настраивать

Нажмите «Ремикс для редактирования», чтобы сделать проект редактируемым.

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

Прежде чем запускать push-уведомления, необходимо настроить сервер и клиент с ключами аутентификации. Подробнее об этом см. в статье «Подпись запросов протокола web push» . Обычно секретные данные хранятся в файле .env , похожем на этот.

VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. Откройте public/index.js .
  2. Замените VAPID_PUBLIC_KEY_VALUE_HERE на значение вашего открытого ключа.

Регистрация работника сферы услуг

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

  1. Замените комментарий // 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);
    
  2. В Chrome откройте консоль DevTools .

  3. Вы должны увидеть сообщение Service worker was registered. вошел в консоль».

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

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

  1. В public/index.js замените комментарий // TODO в subscribeButtonHandler() следующим кодом:

    // 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.');
    }
    
  2. Вернитесь на вкладку приложения и нажмите «Подписаться на push- уведомления». Браузер или операционная система спросят вас, хотите ли вы разрешить сайту отправлять вам push-уведомления.

  3. Выберите «Разрешить» (или эквивалентную фразу, используемую в вашем браузере или операционной системе). В консоли должно появиться сообщение о том, был ли запрос принят или отклонён.

Подписаться на 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 . Возможно, когда-нибудь появится возможность отправлять push-сообщения без отображения видимых пользователю уведомлений ( тихие push-уведомления ), но браузеры не поддерживают такую ​​возможность из-за проблем с конфиденциальностью.

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

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

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

  • Замените комментарий // TODO в unsubscribeButtonHandler() следующим кодом:
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 сервис-воркера следующим кодом:

    let data = event.data.json();
    const image = 'logo.png';
    const options = {
      body: data.options.body,
      icon: image
    }
    self.registration.showNotification(
      data.title,
      options
    );
    
  2. Вернитесь на вкладку приложения.

  3. Нажмите «Уведомить меня» . Вы получите push-уведомление.

  4. Откройте URL-адрес вкладки вашего приложения в других поддерживаемых браузерах. Пройдите процедуру оформления подписки и нажмите «Уведомить всех» . Вы должны получить одинаковое push-уведомление в каждом из них.

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

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

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

  1. Замените комментарий // TODO в обработчике событий notificationclick сервисного работника следующим кодом:

    event.notification.close();
    event.waitUntil(self.clients.openWindow('https://web.dev'));
    
  2. Вернитесь на вкладку приложения, отправьте себе ещё одно уведомление и нажмите на него. Браузер должен открыть новую вкладку и загрузить https://web.dev .

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