Ćwiczenia z programowania: tworzenie klienta powiadomień push

Kate Jeffreys
Kate Jeffreys

Dzięki temu ćwiczeniu w programie dowiesz się krok po kroku, jak utworzyć klienta powiadomień push. Po zakończeniu ćwiczeń z programowania będziesz mieć klienta, który:

  • Subskrybuje powiadomienia push użytkownika.
  • Odbiera wiadomości push i wyświetla je jako powiadomienia.
  • Anuluje subskrypcję powiadomień push dla użytkownika.

To ćwiczenie w Codelabs ma na celu pomóc Ci w nauce przez działanie. Nie omawiamy zbyt wiele pojęć. W artykule Jak działają powiadomienia push, znajdziesz więcej informacji o pojęciach związanych z powiadomieniami push.

Kod serwera tego ćwiczenia w Codelabs jest już gotowy. W tym ćwiczeniu w programie wdrożysz tylko klienta. Aby dowiedzieć się, jak wdrożyć serwer powiadomień push, zapoznaj się z przewodnikiem Codelab: tworzenie serwera powiadomień push.

Pełny kod znajdziesz na stronie push-notifications-client-codelab-complete (źródło).

Zgodność z przeglądarką

Te ćwiczenia z programowania działają w następujących kombinacjach systemów operacyjnych i przeglądarek:

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

Wiemy, że te ćwiczenia z programowania nie działają w następujących systemach operacyjnych (lub w kombinacjach systemów operacyjnych i przeglądarek):

  • macOS: Brave, Edge, Safari
  • iOS

Konfiguracja

Pobierz edytowalną kopię kodu

W trakcie tego ćwiczenia w Codelabs edytor kodu widoczny po prawej stronie tych instrukcji będzie nazywany interfejsem Glitch.

  1. Aby umożliwić edytowanie projektu, kliknij Zremiksuj do edycji.

Konfigurowanie uwierzytelniania

Aby powiadomienia push działały, musisz skonfigurować serwer i klienta za pomocą kluczy uwierzytelniania. Aby dowiedzieć się, dlaczego tak jest, zapoznaj się z sekcją Podpisywanie żądań protokołu Web push.

  1. W interfejsie Glitch kliknij Narzędzia, a następnie Terminal, aby otworzyć terminal Glitch.
  2. W terminalu Glitch uruchom polecenie npx web-push generate-vapid-keys. Skopiuj wartości klucza prywatnego i publicznego.
  3. W interfejsie Glitch otwórz .env i zaktualizuj VAPID_PUBLIC_KEY oraz VAPID_PRIVATE_KEY. Ustaw VAPID_SUBJECT na mailto:test@test.test. Wszystkie te wartości należy ujmować w podwójny cudzysłów. Po wprowadzeniu zmian plik .env powinien wyglądać podobnie do tego:
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
  1. Zamknij terminal Glitch.
  1. Otwórz pokój public/index.js.
  2. Zastąp VAPID_PUBLIC_KEY_VALUE_HERE wartością swojego klucza publicznego.

Rejestrowanie skryptu service worker

Twój klient będzie potrzebować skryptu service worker, który będzie odbierać i wyświetlać powiadomienia. Najlepiej jak najwcześniej zarejestrować skrypt service worker. Więcej informacji znajdziesz w artykule Odbieranie i wyświetlanie przekazanych wiadomości jako powiadomień.

  1. Zastąp komentarz // TODO add startup logic here tym kodem:
// 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. Aby wyświetlić podgląd strony, kliknij Wyświetl aplikację, a potem Pełny ekran pełny ekran.
  1. Naciśnij „Control + Shift + J” (lub „Command + Option + J” na Macu), aby otworzyć Narzędzia deweloperskie.
  2. Kliknij kartę Konsola. Powinien wyświetlić się komunikat Service worker was registered. zalogowany w konsoli.

Prośba o zgodę na wyświetlanie powiadomień push

Nigdy nie proś o zgodę na wysyłanie powiadomień push podczas wczytywania strony. Zamiast tego interfejs powinien zapytać, czy chce otrzymywać powiadomienia push. Gdy już to zrobią (np. przez kliknięcie przycisku), możesz rozpocząć formalny proces uzyskiwania zgody na powiadomienia push z przeglądarki.

  1. W interfejsie Glitch kliknij View Source (Wyświetl źródło), aby wrócić do kodu.
  2. W public/index.js zastąp komentarz // TODO w subscribeButtonHandler() tym kodem:
// 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. Wróć na kartę aplikacji i kliknij Subskrybuj, aby przesłać push. W przeglądarce lub systemie operacyjnym pojawi się pewnie pytanie, czy chcesz zezwolić witrynie na wysyłanie powiadomień push. Kliknij Zezwól (lub inne wyrażenie używane w przeglądarce lub systemie operacyjnym). W konsoli powinien się pojawić komunikat z informacją, czy prośba została zaakceptowana czy odrzucona.

Subskrybuj powiadomienia push

Proces subskrypcji obejmuje interakcję z usługą push kontrolowanej przez dostawcę przeglądarki. Po otrzymaniu informacji o subskrypcji powiadomień push musisz wysłać je na serwer i zadbać o to, aby przez długi czas były przechowywane w bazie danych. Więcej informacji o procesie subskrypcji znajdziesz w artykule na temat subskrybowania powiadomień push klienta.

  1. Dodaj ten zaznaczony kod do pliku 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)
});

Opcja userVisibleOnly musi mieć wartość true. Być może pewnego dnia będzie można wysyłać wiadomości bez wyświetlania powiadomień widocznych dla użytkowników (ciche powiadomienia push), ale przeglądarki nie zezwalają obecnie na taką możliwość ze względu na ochronę prywatności.

Wartość applicationServerKey korzysta z funkcji narzędziowej, która konwertuje ciąg znaków base64 na tablicę Uint8. Ta wartość służy do uwierzytelniania między serwerem a usługą push.

Anulowanie subskrypcji powiadomień push

Gdy użytkownik zasubskrybuje powiadomienia push, w interfejsie użytkownika musi być dostępna opcja anulowania subskrypcji, jeśli zmieni zdanie i nie będzie już chciała otrzymywać takich powiadomień.

  1. Zastąp komentarz // TODO w unsubscribeButtonHandler() tym kodem:
// 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;
}

Odbieranie wiadomości push i wyświetlanie jej jako powiadomień

Jak już wspomnieliśmy, potrzebujesz skryptu service worker do odbierania i wyświetlania wiadomości wysłanych do klienta z Twojego serwera. Więcej informacji znajdziesz w artykule Odbieranie i wyświetlanie przekazanych wiadomości jako powiadomień.

  1. Otwórz public/service-worker.js i zastąp komentarz // TODO w module obsługi zdarzeń push skryptu service worker tym kodem:
// 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. Wróć na kartę aplikacji.
  2. Kliknij Powiadom mnie. Otrzymasz powiadomienie push.
  3. Otwórz adres URL karty aplikacji w innych przeglądarkach (albo nawet na innych urządzeniach), wykonaj procedurę subskrypcji, a potem kliknij Powiadamiaj wszystkich. To samo powiadomienie push powinno dotrzeć we wszystkich przeglądarkach, które subskrybujesz. Więcej informacji o kombinacjach przeglądarki i systemu operacyjnego, o których wiadomo, że działają lub nie działają, znajdziesz w sekcji Zgodność przeglądarek.

Możesz dostosować powiadomienie na wiele sposobów. Aby dowiedzieć się więcej, sprawdź parametry właściwości ServiceWorkerRegistration.showNotification().

Otwieranie adresu URL, gdy użytkownik kliknie powiadomienie

W praktyce będziesz raczej używać powiadomień jako sposobu na ponowne zaangażowanie użytkowników i zachęcenie ich do odwiedzenia Twojej witryny. Żeby to zrobić, musisz jeszcze trochę skonfigurować skrypt service worker.

  1. Zastąp komentarz // TODO w module obsługi zdarzeń notificationclick w skrypcie service worker tym kodem:
// TODO
event.notification.close();
event.waitUntil(self.clients.openWindow('https://web.dev'));
  1. Wróć na kartę aplikacji, wyślij do siebie kolejne powiadomienie i kliknij je. Przeglądarka powinna otworzyć nową kartę i załadować stronę https://web.dev.

Dalsze kroki