この Codelab では、プッシュ通知クライアントを作成する方法について説明します。この Codelab の終了時には、次のことができるクライアントが完成します。
- ユーザーをプッシュ通知に登録します。
- プッシュ メッセージを受信し、通知として表示します。
- ユーザーのプッシュ通知の登録を解除します。
この Codelab は、実際にやってみることで学習できるようにすることを目的としており、コンセプトについてはあまり説明しません。プッシュ通知のコンセプトについては、プッシュ通知の仕組みをご覧ください。
この Codelab のサーバーコードはすでに完成しています。この Codelab では、クライアントのみを実装します。プッシュ通知サーバーを導入する方法については、Codelab: プッシュ通知サーバーを構築するをご覧ください。
push-notifications-client-codelab-complete(ソース)で、完全なコードを確認してください。
ブラウザの互換性
この Codelab は、次のオペレーティング システムとブラウザの組み合わせで動作することが確認されています。
- Windows: Chrome、Edge
- macOS: Chrome、Firefox
- Android: Chrome、Firefox
この Codelab は、以下のオペレーティング システム(またはオペレーティング システムとブラウザの組み合わせ)では動作しないことが確認されています。
- macOS: Brave、Edge、Safari
- iOS
セットアップ
コードの編集可能なコピーを取得する
この手順の右側に表示されるコードエディタは、この Codelab では Glitch UI と呼ばれます。
- [Remix to Edit] をクリックして、プロジェクトを編集可能にします。
認証を設定する
プッシュ通知を機能させるには、認証鍵を使用してサーバーおよびクライアントを設定する必要があります。理由については、ウェブ プッシュ プロトコル リクエストに署名するをご覧ください。
- Glitch UI で [ツール]、[ターミナル] の順にクリックして Glitch ターミナルを開きます。
- Glitch ターミナルで
npx web-push generate-vapid-keys
を実行します。秘密鍵と公開鍵の値をコピーします。 - Glitch UI で
.env
を開き、VAPID_PUBLIC_KEY
とVAPID_PRIVATE_KEY
を更新します。VAPID_SUBJECT
をmailto:test@test.test
に設定します。これらの値はすべて二重引用符で囲む必要があります。更新後、.env
ファイルは次のようになります。
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
- Glitch ターミナルを閉じます。
public/index.js
を開きます。VAPID_PUBLIC_KEY_VALUE_HERE
は、公開鍵の値に置き換えます。
Service Worker を登録する
最終的には、通知を受信して表示する Service Worker をクライアントに必要とします。Service Worker はできる限り早く登録することをおすすめします。詳細については、プッシュされたメッセージを受信して通知として表示するをご覧ください。
// TODO add startup logic here
コメントを次のコードに置き換えます。
// 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);
- サイトをプレビューするには、[アプリを表示] を押してから、[全画面表示] を押します。
- Ctrl+Shift+J(Mac の場合は Command+Option+J)キーを押して DevTools を開きます。
- [Console](コンソール)タブをクリックします。
Service worker was registered.
というメッセージがコンソールに記録されます。
プッシュ通知の使用権限をリクエストする
ページの読み込み時にプッシュ通知を送信する権限をリクエストしないでください。代わりに、プッシュ通知を受け取るかどうかをユーザーに尋ねる UI を作成する必要があります。ユーザーが明示的に確認したら(ボタンのクリックなど)、ブラウザからプッシュ通知の許可を得るための正式なプロセスを開始できます。
- Glitch UI で [View Source] をクリックしてコードに戻ります。
public/index.js
で、subscribeButtonHandler()
の// TODO
コメントを次のコードに置き換えます。
// 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.');
}
- アプリタブに戻り、[プッシュ配信に登録] をクリックします。ブラウザまたはオペレーティング システムから、ウェブサイトによるプッシュ通知の送信を許可するかどうかを尋ねられることがあります。[許可](またはブラウザ/OS で使用されている同等のフレーズ)をクリックします。リクエストが承認されたか拒否されたかを示すメッセージがコンソールに表示されます。
プッシュ通知を登録する
定期購入プロセスでは、ブラウザ ベンダーが制御するウェブサービス(プッシュ サービス)とのやり取りが行われます。プッシュ通知のサブスクリプション情報を取得したら、それをサーバーに送信し、サーバーがデータベースに長期的に保存するようにする必要があります。サブスクリプション プロセスの詳細については、クライアントを push 通知に登録するをご覧ください。
- ハイライト表示された次のコードを
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
にする必要があります。将来的には、ユーザーに表示される通知を表示せずにメッセージをプッシュする(サイレント プッシュ)ことが可能になる可能性がありますが、現在のところ、プライバシー上の懸念から、ブラウザではこの機能が許可されていません。
applicationServerKey
値は、base64 文字列を Uint8Array に変換するユーティリティ関数に依存しています。この値は、サーバー間とプッシュ サービス間の認証に使用されます。
プッシュ通知の登録を解除する
ユーザーがプッシュ通知を登録した後、ユーザーが気が変わってプッシュ通知の受信を停止した場合に備えて、UI に登録解除の方法を提供する必要があります。
unsubscribeButtonHandler()
の// TODO
コメントを次のコードに置き換えます。
// 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;
}
プッシュ メッセージを受信して通知として表示する
前述のように、サーバーからクライアントにプッシュされたメッセージの受信と表示を処理するには、Service Worker が必要です。詳しくは、プッシュされたメッセージを通知として受信して表示するをご覧ください。
public/service-worker.js
を開き、サービス ワーカーのpush
イベント ハンドラの// TODO
コメントを次のコードに置き換えます。
// 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
);
- アプリタブに戻ります。
- [通知を受け取る] をクリックします。プッシュ通知が届きます。
- 他のブラウザ(または他のデバイス)でアプリタブの URL を開き、定期購入のワークフローに沿って [すべて通知] をクリックしてみてください。登録したすべてのブラウザで同じプッシュ通知が届きます。ブラウザの互換性を参照して、動作が確認されているブラウザと OS の組み合わせと、動作が確認されていない組み合わせを確認します。
通知はさまざまな方法でカスタマイズできます。詳細については、ServiceWorkerRegistration.showNotification()
のパラメータをご覧ください。
ユーザーが通知をクリックしたときに URL を開く
実際の運用では、ユーザーの再エンゲージメントを促し、サイトへのアクセスを促す方法として通知を使用します。そのためには、サービス ワーカーをもう少し構成する必要があります。
- サービス ワーカーの
notificationclick
イベント ハンドラの// TODO
コメントを次のコードに置き換えます。
// TODO
event.notification.close();
event.waitUntil(self.clients.openWindow('https://web.dev'));
- [アプリ] タブに戻り、自分に別の通知を送信してから、その通知をクリックします。ブラウザで新しいタブが開き、
https://web.dev
が読み込まれます。
次のステップ
ServiceWorkerRegistration.showNotification()
で、通知をカスタマイズするさまざまな方法を確認してください。- プッシュ通知の仕組みを詳しく理解するには、プッシュ通知の概要をご覧ください。
- Codelab: プッシュ通知サーバーを構築するで、定期購入を管理し、ウェブプッシュ プロトコル リクエストを送信するサーバーの構築方法を確認する。
- 通知生成ツールを使って、通知をカスタマイズできるすべての方法を試すことができます。