Ćwiczenia z programowania: tworzenie klienta powiadomień push

Kate Jeffreys
Kate Jeffreys

Z tego ćwiczenia w Codelabs dowiesz się, jak krok po kroku utworzyć klienta powiadomień push. Na koniec tego ćwiczenia będziesz mieć klienta, który:

  • Subskrybuje powiadomienia push.
  • Odbiera powiadomienia push i wyświetla je jako powiadomienia.
  • Anuluje subskrypcję powiadomień push.

Ten warsztat programistyczny ma na celu pomóc Ci w nauce poprzez działanie i nie skupia się na omawianiu pojęć. Aby dowiedzieć się więcej o pojęciach związanych z powiadomieniami push, przeczytaj artykuł Jak działają powiadomienia push?.

Kod serwera w tym ćwiczeniu jest już gotowy. W tym ćwiczeniu będziesz wdrażać tylko klienta. Aby dowiedzieć się, jak wdrożyć serwer powiadomień push, zapoznaj się z Codelab: tworzenie serwera powiadomień push.

Aby zobaczyć pełny kod, otwórz push-notifications-client-codelab-complete (kod źródłowy).

Zgodność z przeglądarką

To Codelab działa w tych kombinacjach systemów operacyjnych i przeglądarek:

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

Ten warsztat z kodem nie działa w tych systemach operacyjnych (lub kombinacjach systemu operacyjnego i przeglądarki):

  • macOS: Brave, Edge, Safari.
  • iOS

Konfiguracja

Pobieranie edytowalnej kopii kodu

W tym samouczku edytor kodu widoczny po prawej stronie tych instrukcji będzie nazywany interfejsem Glitch.

  1. Kliknij Remixuj do edycji, aby umożliwić edycję projektu.

Konfigurowanie uwierzytelniania

Zanim zaczniesz korzystać z powiadomień push, musisz skonfigurować serwer i klienta za pomocą kluczy uwierzytelniających. Aby dowiedzieć się, dlaczego tak się dzieje, przeczytaj artykuł Podpisywanie żądań wysyłanych za pomocą protokołu web push.

  1. W interfejsie Glitch kliknij Narzędzia, a następnie Terminal, aby otworzyć terminal Glitch.
  2. W terminalu Glitch uruchom npx web-push generate-vapid-keys. Skopiuj wartości klucza prywatnego i klucza 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 powinny być zapisane w podwójnych cudzysłowach. Po wprowadzeniu zmian plik .env powinien wyglądać tak:
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ą klucza publicznego.

Rejestrowanie skryptu service worker

Ostatecznie klient będzie potrzebować service workera do odbierania i wyświetlania powiadomień. Najlepiej zarejestrować service workera jak najszybciej. Więcej informacji znajdziesz w artykule Otrzymywanie i wyświetlanie wiadomości przesyłanych jako powiadomienia.

  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ę. Następnie kliknij Pełny ekran pełny ekran.
  1. Aby otworzyć Narzędzia dla programistów, naciśnij `Control+Shift+J` (lub `Command+Option+J` na Macu).
  2. Kliknij kartę Konsola. W Konsoli powinien pojawić się komunikatService worker was registered..

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 użytkownika powinien pytać, czy chce otrzymywać powiadomienia push. Gdy użytkownik wyraźnie potwierdzi (np. kliknięciem przycisku), możesz rozpocząć formalny proces uzyskania uprawnień do wysyłania powiadomień push z przeglądarki.

  1. Aby wrócić do kodu, w interfejsie Glitch kliknij Wyświetl źródło.
  2. W pliku public/index.js zastąp komentarz // TODO w pliku 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óć do karty aplikacji i kliknij Subskrybuj powiadomienia push. Przeglądarka lub system operacyjny prawdopodobnie zapyta, czy chcesz otrzymywać powiadomienia push z witryny. Kliknij Zezwól (lub inną odpowiednią frazę używaną przez Twoją przeglądarkę lub system operacyjny). W konsoli powinien pojawić się komunikat informujący, czy prośba została zaakceptowana, czy odrzucona.

Subskrybuj powiadomienia push

Proces subskrypcji wymaga interakcji z usługą internetową kontrolowaną przez dostawcę przeglądarki, zwaną usługą push. Gdy otrzymasz informacje o subskrypcji powiadomień push, musisz je wysłać na serwer, który przechowa je w bazie danych na dłuższy czas. Aby dowiedzieć się więcej o procesie subskrypcji, przeczytaj artykuł Subskrypcja powiadomień push przez klienta.

  1. Dodaj do pliku subscribeButtonHandler() ten wyróżniony kod:
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. Może się zdarzyć, że pewnego dnia będzie można wysyłać wiadomości bez wyświetlania powiadomień widocznych dla użytkownika (cicha wysyłka), ale obecnie przeglądarki nie umożliwiają takiej funkcji ze względu na kwestie związane z prywatnością.

Wartość applicationServerKey opiera się na funkcji pomocniczej, która konwertuje ciąg znaków w formacie base64 na tablicę Uint8. Ta wartość jest używana do uwierzytelniania między serwerem a usługą push.

Anulowanie subskrypcji powiadomień push

Gdy użytkownik zasubskrybuje powiadomienia push, interfejs musi umożliwiać rezygnację z subskrypcji, jeśli użytkownik zmieni zdanie i nie będzie już chciał otrzymywać powiadomień push.

  1. Zastąp komentarz // TODO w pliku 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 i wyświetlanie powiadomień push

Jak już wspomnieliśmy, do obsługiwania odbierania i wyświetlania wiadomości wysyłanych na klienta z serwera potrzebny jest Ci serwis worker. Więcej informacji znajdziesz w artykule Odbieranie i wyświetlanie wiadomości push jako powiadomień.

  1. Otwórz plik public/service-worker.js i w obiekcie service worker zastąp komentarz // TODO w obiekcie push obsługującym zdarzenie 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óć do karty aplikacji.
  2. Kliknij Powiadamiaj mnie. Otrzymasz powiadomienie push.
  3. Spróbuj otworzyć adres URL karty aplikacji w innych przeglądarkach (lub na innych urządzeniach), przejść przez proces subskrypcji, a następnie kliknąć Powiadomij wszystkich. Powinieneś otrzymywać te same powiadomienia push we wszystkich przeglądarkach, w których się subskrybujesz. Aby zobaczyć listę kombinacji przeglądarek i systemów operacyjnych, które działają lub nie działają, zapoznaj się z artykułem Zgodność przeglądarki.

Powiadomienie możesz dostosować na wiele sposobów. Aby dowiedzieć się więcej, zapoznaj się z parametrami funkcji ServiceWorkerRegistration.showNotification().

Otwieranie adresu URL po kliknięciu powiadomienia przez użytkownika

W praktyce prawdopodobnie użyjesz powiadomienia, aby ponownie zaangażować użytkownika i zachęcić go do odwiedzenia Twojej witryny. Aby to zrobić, musisz nieco bardziej skonfigurować usługę.

  1. Zastąp komentarz // TODO w obiekcie notificationclick w obiekcie notificationclick kodem:
// TODO
event.notification.close();
event.waitUntil(self.clients.openWindow('https://web.dev'));
  1. Wróć do karty aplikacji, wyślij do siebie kolejne powiadomienie, a potem kliknij to powiadomienie. Przeglądarka powinna otworzyć nową kartę i wczytać https://web.dev.

Dalsze kroki