1. Omówienie
Komunikaty push to prosty i skuteczny sposób na ponowne zaangażowanie użytkowników. Z tego ćwiczenia w Codelabs dowiesz się, jak dodać powiadomienia push do aplikacji internetowej.
Czego się nauczysz
- Jak zasubskrybować wiadomości push i anulować ich subskrypcję
- Obsługa przychodzących wiadomości push
- Jak wyświetlić powiadomienie
- Jak reagować na kliknięcia powiadomień
Czego potrzebujesz
- Chrome 52 lub nowsza,
- Serwer WWW dla Chrome lub Twój własny serwer WWW.
- Edytor tekstu
- Podstawowa wiedza o językach HTML, CSS, JavaScript i Narzędziach deweloperskich w Chrome
- Przykładowy kod (zobacz konfigurację).
2. Konfiguracja
Pobierz przykładowy kod
Przykładowy kod do ćwiczeń z programowania można pobrać na 2 sposoby:
- Sklonuj repozytorium Git:
git clone https://github.com/GoogleChrome/push-notifications.git
- Pobierz plik ZIP:
Jeśli pobierzesz plik źródłowy jako plik ZIP, rozpakowanie go spowoduje utworzenie folderu głównego push-notifications-master
.
Instalowanie i weryfikowanie serwera WWW
Chociaż możesz używać własnego serwera WWW, to ćwiczenie w Codelabs działa dobrze z aplikacją Serwer WWW dla Chrome. Jeśli nie masz jeszcze zainstalowanej tej aplikacji, możesz ją pobrać z Chrome Web Store:
Po zainstalowaniu aplikacji Serwer internetowy dla Chrome kliknij skrót Aplikacje na pasku zakładek:
W oknie Aplikacje kliknij ikonę Serwer WWW:
Zostanie wyświetlone następujące okno dialogowe, które umożliwia skonfigurowanie lokalnego serwera WWW:
Kliknij przycisk Wybierz folder i w pobranym folderze push-notifications
wybierz folder app
. Dzięki temu możesz udostępniać wykonywaną pracę pod adresem URL widocznym w sekcji Adresy URL serwerów WWW w oknie.
W sekcji Opcje zaznacz pole wyboru Automatycznie pokazuj plik index.html, jak pokazano poniżej:
Następnie zatrzymaj i ponownie uruchom serwer, przesuwając przełącznik Serwer WWW: STARTED w lewo, a następnie z powrotem w prawo.
Kliknij adres URL serwera WWW, aby otworzyć swoją witrynę w przeglądarce. Powinna wyświetlić się strona podobna do tej, choć w Twojej wersji może być widoczny adres 127.0.0.1:8887:
Zawsze aktualizuj skrypt service worker
W trakcie programowania warto zadbać o to, by skrypt service worker był zawsze aktualny i zawierał najnowsze zmiany.
Aby to zrobić w Chrome:
- Otwórz kartę Push Codelabs.
- Otwórz Narzędzia deweloperskie: Ctrl+Shift-I w systemach Windows i Linux lub Cmd-Option-I w systemie macOS.
- Wybierz panel Application, kliknij kartę Service Workers i zaznacz pole wyboru Aktualizuj przy ponownym załadowaniu. Jeśli to pole wyboru jest zaznaczone, skrypt service worker jest wymuszany przy każdym odświeżeniu strony.
3. Rejestrowanie skryptu service worker
Zwróć uwagę, że w katalogu app
masz pusty plik o nazwie sw.js
. Ten plik będzie skryptem service worker. Na razie może pozostać puste. Później dodasz do niego kod.
Najpierw musisz zarejestrować ten plik jako skrypt service worker.
Twoja strona app/index.html
wczytuje się scripts/main.js
. Rejestrujesz skrypt service worker w tym pliku JavaScript.
Dodaj do pliku scripts/main.js
ten kod:
if ('serviceWorker' in navigator && 'PushManager' in window) {
console.log('Service Worker and Push are supported');
navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
console.log('Service Worker is registered', swReg);
swRegistration = swReg;
})
.catch(function(error) {
console.error('Service Worker Error', error);
});
} else {
console.warn('Push messaging is not supported');
pushButton.textContent = 'Push Not Supported';
}
Ten kod sprawdza, czy Twoja przeglądarka obsługuje mechanizmy Service Worker i wiadomości push. Jeśli są one obsługiwane, kod umożliwia zarejestrowanie pliku sw.js
.
Wypróbuj
Sprawdź zmiany, odświeżając kartę Ćwiczenia z programowania push w przeglądarce.
Sprawdź wartość Service Worker is registered message
w konsoli w Narzędziach deweloperskich w Chrome, na przykład:
Pobieranie kluczy serwera aplikacji
Aby skorzystać z tego ćwiczenia z programowania, musisz wygenerować klucze serwera aplikacji. Możesz to zrobić w witrynie towarzyszącej: web-push-codelab.glitch.me
Tutaj możesz wygenerować parę kluczy (publiczny i prywatny).
Skopiuj klucz publiczny do scripts/main.js
, zastępując wartość <Your Public Key>
:
const applicationServerPublicKey = '<Your Public Key>';
Ważne: nigdy nie umieszczaj klucza prywatnego w aplikacji internetowej.
4. Stan zainicjowania
Obecnie przycisk Włącz w aplikacji internetowej jest wyłączony i nie można go kliknąć. Dzieje się tak, ponieważ dobrym rozwiązaniem jest domyślne wyłączenie przycisku push i włączenie go, gdy dowiesz się, że przeglądarka obsługuje przesyłanie wiadomości push i możesz sprawdzić, czy użytkownik obecnie subskrybuje wiadomości.
Musisz utworzyć 2 funkcje w funkcji scripts/main.js
:
initializeUI
, aby sprawdzić, czy użytkownik obecnie subskrybuje kanał.updateBtn
, aby włączyć przycisk i zmienić tekst w zależności od tego, czy użytkownik ma subskrypcję
Dodaj funkcję initializeUI
do elementu main.js
w ten sposób:
function initializeUI() {
// Set the initial subscription value
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
isSubscribed = !(subscription === null);
if (isSubscribed) {
console.log('User IS subscribed.');
} else {
console.log('User is NOT subscribed.');
}
updateBtn();
});
}
Nowa metoda używa metody swRegistration
z poprzedniego kroku, pobiera z niej właściwość pushManager
i wywołuje w niej właściwość getSubscription()
.
pushManager
getSubscription()
zwraca obietnicę, która obowiązuje w przypadku bieżącej subskrypcji (jeśli istnieje). W przeciwnym razie zwraca wartość null
. Dzięki temu możesz sprawdzić, czy użytkownik już subskrybuje kanał, ustawić wartość isSubscribed
, a następnie wywołać updateBtn()
, by zaktualizować przycisk.
Dodaj funkcję updateBtn()
do zbioru danych main.js
:
function updateBtn() {
if (isSubscribed) {
pushButton.textContent = 'Disable Push Messaging';
} else {
pushButton.textContent = 'Enable Push Messaging';
}
pushButton.disabled = false;
}
Ta funkcja włącza przycisk i zmienia jego tekst w zależności od tego, czy użytkownik ma subskrypcję.
Ostatnią rzeczą, jaką musisz zrobić, jest wywołanie metody initializeUI()
, gdy skrypt service worker jest zarejestrowany w main.js
:
navigator.serviceWorker.register('sw.js')
.then(function(swReg) {
console.log('Service Worker is registered', swReg);
swRegistration = swReg;
initializeUI();
})
Wypróbuj
Odśwież kartę Push Codelabs. Przycisk Włącz wiadomości push powinien być włączony (możesz go kliknąć), a w konsoli powinien pojawić się User is NOT subscribed
.
W miarę wykonywania kolejnych ćwiczeń z programowania tekst przycisku powinien zmieniać się za każdym razem, gdy subskrybujesz lub anulujesz subskrypcję.
5. Subskrybowanie użytkownika
Obecnie przycisk Włącz wiadomości push jest mało przydatny. Zajmijmy się tym.
W funkcji initializeUI()
dodaj odbiornik kliknięć przycisku:
function initializeUI() {
pushButton.addEventListener('click', function() {
pushButton.disabled = true;
if (isSubscribed) {
// TODO: Unsubscribe user
} else {
subscribeUser();
}
});
// Set the initial subscription value
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
isSubscribed = !(subscription === null);
updateSubscriptionOnServer(subscription);
if (isSubscribed) {
console.log('User IS subscribed.');
} else {
console.log('User is NOT subscribed.');
}
updateBtn();
});
}
Gdy użytkownik kliknie przycisk, wyłączasz go tylko po to, aby uniemożliwić mu ponowne kliknięcie. Subskrypcja komunikatów push może trochę potrwać.
Następnie wywołasz „subscribeUser()
”, jeśli użytkownik nie ma obecnie subskrypcji. W tym celu musisz wkleić ten kod do usługi scripts/main.js
:
function subscribeUser() {
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(function(subscription) {
console.log('User is subscribed.');
updateSubscriptionOnServer(subscription);
isSubscribed = true;
updateBtn();
})
.catch(function(error) {
console.error('Failed to subscribe the user: ', error);
updateBtn();
});
}
Przeanalizujmy działanie tego kodu i jego subskrybowanie w wiadomościach push.
Najpierw bierzesz klucz publiczny serwera aplikacji, który jest zakodowany w standardzie Base64 URL, i przekształcasz go na UInt8Array
, ponieważ jest to oczekiwany wynik wywołania subscribe()
. Funkcja urlB64ToUint8Array()
znajduje się na górze arkusza scripts/main.js
.
Po przekonwertowaniu wartości wywołasz metodę subscribe()
w pushManager
skryptu service worker, przekazując klucz publiczny serwera aplikacji i wartość userVisibleOnly: true
.
const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
Parametr userVisibleOnly
daje pewność, że powiadomienie będzie wyświetlane przy każdym wysłaniu wiadomości push. Obecnie ta wartość jest wymagana i musi mieć wartość true (prawda).
Wywołanie subscribe()
zwraca obietnicę, która zostanie zrealizowana po wykonaniu tych czynności:
- Użytkownik zezwolił na wyświetlanie powiadomień.
- Przeglądarka wysłała żądanie sieciowe do usługi push, aby pobrać dane wymagane do wygenerowania
PushSubscription
.
Jeśli te czynności zostały wykonane, obietnica subscribe()
zostanie zrealizowana z PushSubscription
. Jeśli użytkownik nie przyzna uprawnień lub wystąpi problem z zasubskrybowaniem użytkownika, obietnica zostanie odrzucona z powodu błędu. W ramach ćwiczenia w Codelabs uzyskasz następujący łańcuch obietnic:
swRegistration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: applicationServerKey
})
.then(function(subscription) {
console.log('User is subscribed.');
updateSubscriptionOnServer(subscription);
isSubscribed = true;
updateBtn();
})
.catch(function(err) {
console.log('Failed to subscribe the user: ', err);
updateBtn();
});
Dzięki temu możesz uzyskać subskrypcję i traktować użytkownika jako subskrybenta lub wykryć błąd i zarejestrować go w konsoli. W obu przypadkach wywołujesz funkcję updateBtn()
, by upewnić się, że przycisk został ponownie włączony i ma odpowiedni tekst.
W prawdziwej aplikacji funkcja updateSubscriptionOnServer()
służy do wysyłania danych subskrypcji do backendu. W przypadku ćwiczeń z programowania wystarczy wyświetlić subskrypcję w interfejsie. Dodaj do scripts/main.js
tę funkcję:
function updateSubscriptionOnServer(subscription) {
// TODO: Send subscription to application server
const subscriptionJson = document.querySelector('.js-subscription-json');
const subscriptionDetails =
document.querySelector('.js-subscription-details');
if (subscription) {
subscriptionJson.textContent = JSON.stringify(subscription);
subscriptionDetails.classList.remove('is-invisible');
} else {
subscriptionDetails.classList.add('is-invisible');
}
}
Wypróbuj
Otwórz kartę Push Codelabs, odśwież stronę i kliknij przycisk. Zobaczysz prośbę o przyznanie uprawnień podobną do tej:
Jeśli przyznasz uprawnienie, w konsoli powinien pojawić się User is subscribed
zalogowany użytkownik. Tekst przycisku zmieni się na Wyłącz wiadomości push i będzie można wyświetlić subskrypcję w postaci danych JSON u dołu strony.
6. Odmowa uprawnień do nicka
Nie rozwiązano jeszcze problemu związanego z zablokowaniem prośby o uprawnienia przez użytkownika. Trzeba to przemyśleć, ponieważ jeśli użytkownik zablokuje to uprawnienie, aplikacja internetowa nie będzie mogła ponownie wyświetlić prośby o przyznanie uprawnień i nie będzie mogła zasubskrybować tego użytkownika. Musisz przynajmniej wyłączyć przycisk, aby użytkownik wiedział, że nie można go użyć.
Najlepszym miejscem do tego scenariusza jest funkcja updateBtn()
. Wystarczy, że sprawdzisz wartość Notification.permission
, na przykład:
function updateBtn() {
if (Notification.permission === 'denied') {
pushButton.textContent = 'Push Messaging Blocked';
pushButton.disabled = true;
updateSubscriptionOnServer(null);
return;
}
if (isSubscribed) {
pushButton.textContent = 'Disable Push Messaging';
} else {
pushButton.textContent = 'Enable Push Messaging';
}
pushButton.disabled = false;
}
Wiesz, że jeśli uprawnienie ma wartość denied
, użytkownik nie może rozpocząć subskrypcji i nie można zrobić nic więcej, dlatego najlepszym sposobem jest trwałe wyłączenie tego przycisku.
Wypróbuj
Ponieważ w poprzednim kroku przyznano aplikacji internetowej uprawnienia, musisz kliknąć i w kółku na pasku adresu URL i zmienić uprawnienia Powiadomienia na Użyj globalnej wartości domyślnej (Zapytaj).
Po zmianie tego ustawienia odśwież stronę i kliknij przycisk Włącz wiadomości push, a następnie wybierz Zablokuj w oknie uprawnień. Przycisk zostanie wyłączony i wyświetli się komunikat Komunikaty push są zablokowane.
Dzięki tej zmianie możesz zasubskrybować konto użytkownika, zapoznając się z możliwymi scenariuszami przyznawania uprawnień.
7. Obsługa zdarzenia push
Zanim nauczysz się wysyłać wiadomości push z backendu, musisz zastanowić się, co faktycznie się stanie, gdy subskrybent otrzyma taką wiadomość.
Gdy aktywujesz komunikat push, przeglądarka otrzymuje ten komunikat, ustala, do którego skryptu service worker jest wymagany, wybudza go i wysyła zdarzenie push. Musisz nasłuchiwać tego zdarzenia, aby wyświetlić powiadomienie.
Dodaj do pliku sw.js
ten kod:
self.addEventListener('push', function(event) {
console.log('[Service Worker] Push Received.');
console.log(`[Service Worker] Push had this data: "${event.data.text()}"`);
const title = 'Push Codelab';
const options = {
body: 'Yay it works.',
icon: 'images/icon.png',
badge: 'images/badge.png'
};
event.waitUntil(self.registration.showNotification(title, options));
});
Przeanalizujmy ten kod. Nasłuchujesz zdarzeń push
w skrypcie service worker, dodając detektor zdarzeń:
self.addEventListener('push', ... );
self
to prawdopodobnie nowa usługa, chyba że znasz już narzędzie Web Worker. W pliku skryptu service worker self
odwołuje się do samego skryptu).
Po otrzymaniu wiadomości push zostanie wywołany detektor zdarzeń i utworzysz powiadomienie, wywołując funkcję showNotification()
we właściwości registration
skryptu service worker. showNotification()
wymaga title
; możesz też nadać mu obiekt options
, aby ustawić treść wiadomości, ikonę i plakietkę. W chwili pisania plakietka jest używana tylko na urządzeniach z Androidem.
const title = 'Push Codelab';
const options = {
body: 'Yay it works.',
icon: 'images/icon.png',
badge: 'images/badge.png'
};
self.registration.showNotification(title, options);
Ostatnią sprawą, o której należy wspomnieć w zakresie obsługi zdarzeń push
, jest event.waitUntil()
. Ta metoda wymaga, aby przeglądarka umożliwiała przeglądarce utrzymanie aktywności i działania skryptu service worker do momentu zrealizowania przekazanej obietnicy.
Aby powyższy kod był bardziej zrozumiały, możesz go zmodyfikować w następujący sposób:
const notificationPromise = self.registration.showNotification(title, options);
event.waitUntil(notificationPromise);
Teraz gdy masz już omówione zdarzenia push, czas przetestować je.
Wypróbuj
Dzięki obsłudze zdarzeń push w mechanizmie Service Worker możesz wywołać fałszywe zdarzenie push, by sprawdzić, co się stanie po otrzymaniu wiadomości.
W swojej aplikacji internetowej zasubskrybuj wiadomości push i sprawdź, czy w konsoli jest wyświetlany komunikat User IS subscribed
. W panelu Application (Aplikacja) w Narzędziach deweloperskich na karcie Service Workers kliknij przycisk Push:
Po kliknięciu przycisku Przekaż powinno wyświetlić się takie powiadomienie:
Uwaga: jeśli ten krok nie zadziała, spróbuj wyrejestrować skrypt service worker za pomocą linku Wyrejestruj w panelu aplikacji Narzędzi deweloperskich, poczekaj na jego zatrzymanie i załaduj stronę ponownie.
8. Kliknięcie powiadomienia
Jeśli klikniesz jedno z tych powiadomień, nic się nie dzieje. Możesz obsługiwać kliknięcia powiadomień, nasłuchując zdarzeń notificationclick
w mechanizmie service worker.
Zacznij od dodania detektora notificationclick
w sw.js
:
self.addEventListener('notificationclick', function(event) {
console.log('[Service Worker] Notification click received.');
event.notification.close();
event.waitUntil(
clients.openWindow('https://developers.google.com/web')
);
});
Gdy użytkownik kliknie powiadomienie, wywołany jest detektor zdarzeń notificationclick
.
Kod najpierw zamyka kliknięte powiadomienie:
event.notification.close();
Następnie otworzy się nowe okno lub nowa karta, która wczytuje adres URL https://developers.google.com/web
. Możesz to zmienić.
event.waitUntil(
clients.openWindow('https://developers.google.com/web/')
);
event.waitUntil()
dba o to, aby przeglądarka nie zakończyła skryptu service worker przed wyświetleniem nowego okna lub karty.
Wypróbuj
Spróbuj ponownie wywołać wiadomość push w Narzędziach deweloperskich i kliknij powiadomienie. Powiadomienie zostanie zamknięte i otworzy się nowa karta.
9. Wysyłanie wiadomości push
Wiesz już, że Twoja aplikacja internetowa może wyświetlać powiadomienia za pomocą Narzędzi deweloperskich. Wiesz już, jak zamknąć powiadomienie jednym kliknięciem. Następnym krokiem jest wysłanie wiadomości push.
Zwykle wymagałoby to wysłania subskrypcji ze strony internetowej do backendu. Backend aktywuje wiadomość push, wysyłając wywołanie interfejsu API do punktu końcowego w subskrypcji.
To wykracza poza zakres tego ćwiczenia w Codelabs, ale możesz użyć witryny towarzyszącej ( web-push-codelab.glitch.me), aby wywołać rzeczywisty komunikat push. Wklej subskrypcję na dole strony:
Następnie wklej ten kod w witrynie towarzyszącej w obszarze tekstowym Subskrypcja do wysłania:
W sekcji SMS do wysłania wpisz dowolny ciąg znaków, który chcesz wysłać w wiadomości push.
Kliknij przycisk Wyślij wiadomość push.
Otrzymasz wtedy wiadomość push. Użyty tekst zostanie zarejestrowany w konsoli.
To powinno dać Ci szansę na przetestowanie wysyłania i odbierania danych oraz na manipulowanie powiadomieniami.
Aplikacja towarzysząca to po prostu serwer węzłów, który używa biblioteki web-push do wysyłania wiadomości. Warto zapoznać się z organizacją web-push-libs na GitHubie, aby dowiedzieć się, z których bibliotek możesz wysyłać komunikaty push. Służy to obsługi wielu szczegółów potrzebnych do aktywowania wiadomości push.
10. Anuluj subskrypcję użytkownika
Jedynym, czego brakuje, jest możliwość anulowania subskrypcji push. Aby to zrobić, musisz zadzwonić pod numer unsubscribe()
na PushSubscription
.
Wróć do pliku scripts/main.js
i zmień odbiornik kliknięć pushButton
w initializeUI()
na taki:
pushButton.addEventListener('click', function() {
pushButton.disabled = true;
if (isSubscribed) {
unsubscribeUser();
} else {
subscribeUser();
}
});
Zwróć uwagę, że zamierzasz wywołać nową funkcję unsubscribeUser()
. Ta funkcja pobiera bieżącą subskrypcję i wywołuje w niej funkcję unsubscribe()
. Dodaj do scripts/main.js
ten kod:
function unsubscribeUser() {
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
return subscription.unsubscribe();
}
})
.catch(function(error) {
console.log('Error unsubscribing', error);
})
.then(function() {
updateSubscriptionOnServer(null);
console.log('User is unsubscribed.');
isSubscribed = false;
updateBtn();
});
}
Przyjrzyjmy się tej funkcji.
Po pierwsze, aby uzyskać aktualną subskrypcję, zadzwoń pod numer getSubscription()
:
swRegistration.pushManager.getSubscription()
Zwraca obietnicę, której wartość występuje przy użyciu parametru PushSubscription
(jeśli istnieje). w przeciwnym razie zwraca null
. Jeśli istnieje subskrypcja, wywołujesz przy niej unsubscribe()
, przez co PushSubscription
jest nieprawidłowy.
swRegistration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
// TODO: Tell application server to delete subscription
return subscription.unsubscribe();
}
})
.catch(function(error) {
console.log('Error unsubscribing', error);
})
Wywołanie unsubscribe()
zwraca obietnicę, ponieważ realizacja może trochę potrwać. Zwrócisz tę obietnicę, więc kolejne then()
w łańcuchu czekają, aż unsubscribe()
się skończy. Dodasz też moduł obsługi żądań (catch) na wypadek, gdyby wywołanie unsubscribe()
zakończyło się błędem. Potem możesz zaktualizować interfejs użytkownika.
.then(function() {
updateSubscriptionOnServer(null);
console.log('User is unsubscribed.');
isSubscribed = false;
updateBtn();
})
Wypróbuj
W aplikacji internetowej powinno być możliwe kliknięcie Włącz wiadomości push lub Wyłącz wiadomości push. W dziennikach pojawi się informacja, że użytkownik został zasubskrybowany lub zrezygnował z subskrypcji.
11. Zakończono
Gratulujemy ukończenia tego ćwiczenia z programowania.
Dzięki temu ćwiczeniu w Codelabs dowiesz się, jak zacząć korzystać z aplikacji internetowej, dodając do niej powiadomienia push. Aby dowiedzieć się więcej o działaniu powiadomień internetowych, zapoznaj się z tymi dokumentami.
Jeśli chcesz wdrożyć w swojej witrynie powiadomienia push, rozważ dodanie obsługi starszych przeglądarek lub niestandardowych przeglądarek, które używają GCM. Więcej informacji
Więcej informacji
- Powiadomienia push w internecie: dokumentacja z podstawami dotyczącymi witryn.
- Biblioteki Web push: biblioteki web push, w tym Node.js, PHP, Java, Python, C i C#.