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

Push-уведомления в Stencil: как реализовать и управлять

Push-уведомления — это механизм, позволяющий веб-приложениям уведомлять пользователей о событиях, даже если они не находятся в активной сессии. Это один из самых эффективных способов держать пользователей в курсе событий, будь то обновления, новости или важные уведомления.

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

Для начала необходимо создать проект с использованием Stencil, если он еще не был подготовлен. Это можно сделать с помощью команды:

npm init stencil

После этого выбирается тип проекта, и Stencil готов к разработке.

Регистрация сервис-воркера

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

В Stencil сервис-воркеры можно зарегистрировать в одном из компонентов или в основном файле index.ts. Пример регистрации:

if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js').then((registration) => {
    console.log('Service Worker registered with scope:', registration.scope);
  }).catch((error) => {
    console.log('Service Worker registration failed:', error);
  });
}

Этот код проверяет наличие поддержки сервис-воркеров в браузере, а затем пытается зарегистрировать его. Файл service-worker.js должен быть доступен в корневой директории проекта, и в нем будет реализована логика обработки push-уведомлений.

Запрос разрешения на получение уведомлений

Перед тем как начать отправлять push-уведомления, необходимо запросить у пользователя разрешение. Это делается с помощью метода Notification.requestPermission(), который возвращает промис, разрешение на отправку уведомлений.

Пример запроса разрешения:

Notification.requestPermission().then((permission) => {
  if (permission === 'granted') {
    console.log('Permission granted for push notifications');
  } else {
    console.log('Permission denied for push notifications');
  }
});

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

Подписка на Push-сервис

После того как пользователь дал разрешение на получение уведомлений, следующий шаг — это подписка на push-сервис. Для этого используется API PushManager.

Подписка выполняется через сервис-воркер, используя метод pushManager.subscribe():

navigator.serviceWorker.ready.then((registration) => {
  registration.pushManager.subscribe({
    userVisibleOnly: true,  // Уведомления будут видимы для пользователя
    applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
  }).then((subscription) => {
    console.log('User is subscribed:', subscription);
    // Отправка данных подписки на сервер для дальнейшей отправки уведомлений
  }).catch((error) => {
    console.error('Failed to subscribe the user: ', error);
  });
});

Здесь publicVapidKey — это публичный ключ, используемый для генерации подписки. Этот ключ должен быть преобразован в формат Uint8Array. Важно также отметить параметр userVisibleOnly: true, который гарантирует, что уведомления будут отображаться для пользователя.

Функция urlBase64ToUint8Array() выполняет преобразование публичного ключа в формат, подходящий для подписки. Пример такой функции:

function urlBase64ToUint8Array(base64String) {
  const padding = '='.repeat((4 - base64String.length % 4) % 4);
  const base64 = (base64String + padding)
    .replace(/\-/g, '+')
    .replace(/_/g, '/');
  const rawData = atob(base64);
  const outputArray = new Uint8Array(rawData.length);
  for (let i = 0; i < rawData.length; ++i) {
    outputArray[i] = rawData.charCodeAt(i);
  }
  return outputArray;
}

Отправка Push-уведомлений

Отправка уведомлений осуществляется сервером, который должен использовать информацию о подписке пользователя, полученную в предыдущем шаге. Сервер отправляет push-уведомление через push-сервис (например, используя библиотеку web-push для Node.js).

Пример отправки уведомления с использованием Node.js:

const webpush = require('web-push');

const pushSubscription = { /* данные подписки из клиента */ };
const payload = JSON.stringify({ title: 'Новое уведомление', message: 'Проверьте новое сообщение!' });

const options = {
  vapidDetails: {
    subject: 'mailto:example@domain.com',
    publicKey: 'YOUR_PUBLIC_VAPID_KEY',
    privateKey: 'YOUR_PRIVATE_VAPID_KEY'
  },
  TTL: 60  // Время жизни уведомления (в секундах)
};

webpush.sendNotification(pushSubscription, payload, options).then(() => {
  console.log('Push notification sent successfully');
}).catch((error) => {
  console.error('Error sending push notification:', error);
});

Здесь используется библиотека web-push, которая позволяет взаимодействовать с Push API для отправки уведомлений. Важно настроить VAPID-ключи для безопасности.

Обработка Push-уведомлений на клиенте

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

Пример обработки push-сообщений в service-worker.js:

self.addEventListener('push', (event) => {
  const data = event.data.json();
  const options = {
    body: data.message,
    icon: 'icon.png',
    badge: 'badge.png',
    vibrate: [200, 100, 200],
  };

  event.waitUntil(
    self.registration.showNotification(data.title, options)
  );
});

В этом примере сервис-воркер отображает уведомление с заданным текстом, иконкой, а также включает вибрацию устройства.

Обновление и отмена подписок

В процессе работы с push-уведомлениями может возникнуть необходимость отменить подписку или обновить её, например, при смене ключей или для управления устаревшими подписками. Это можно сделать с помощью методов unsubscribe() и update() API PushManager:

navigator.serviceWorker.ready.then((registration) => {
  registration.pushManager.getSubscription().then((subscription) => {
    if (subscription) {
      subscription.unsubscribe().then(() => {
        console.log('User unsubscribed from push notifications');
      }).catch((error) => {
        console.error('Error unsubscribing user:', error);
      });
    }
  });
});

Этот код позволяет отписать пользователя от получения push-уведомлений, например, если он отменяет подписку через настройки.

Советы по улучшению производительности

  • Использование background sync: Если уведомление связано с данным процессом (например, получение обновлений), можно использовать Background Sync для асинхронной обработки данных.
  • Lazy loading уведомлений: Для улучшения производительности и снижения нагрузки на браузер рекомендуется загружать уведомления только по запросу или при необходимости.
  • Микроанимations: Можно добавить анимации к уведомлениям для повышения визуальной привлекательности.

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