- この記事はPWAアドベントカレンダーの5日目の記事です
Webアプリにおけるプッシュ通知
- PWAを代表する機能としてプッシュ通知があげられることがよくあると思います(iPhone/Safariだとまだ使えないんですがね)
- Webアプリにおけるプッシュ通知はPushAPIとNotificationAPIというの2つの仕組みからなっています
PushAPI
- PushAPIはサーバからの通知を受け取ることができるAPIです
NotificationAPI
- NotificationAPIはユーザに対して通知を送ることができるAPIです
一連の流れ
- Webアプリにおけるプッシュ通知送信までの一連の流れは、PushAPIがサーバからの通知を受け取り、NotificationAPIを呼び出してユーザに通知を送ります
- それぞれの使い方を整理しようと思いましたが思いの外大変だったので今回はNotificationAPIを紹介します
NotificationAPIの使い方
- NotificationAPIはユーザに通知を送るAPIでした
- 通知を送るためには事前に許可を得る必要があります
- 見た瞬間に拒否を押してしまうあれですね・・・(許可を得るタイミングはよく考えて実装しましょう!)
- というわけで許可をとるフェーズと通知を送るフェーズの2つに分けて説明していきます
許可を取るフェーズ
- 通知の許可を得るためには
Notification.requestPermission()
を実行することでユーザに尋ねることができます -
requestPermission()
はPromiseを返し、ユーザが 許可 or ブロック を選択するとresolveされて結果を取得できます- 許可なら
granted
、ブロックならdenided
という値を取得できます
- 許可なら
- 以下のコードで試すことができます
<button id="confirm">通知の許可を取得する</button>
<script>
document.getElementById('confirm').addEventListener('click', () => {
Notification.requestPermission().then(permission => {
alert(permission); // granted or denied
});
});
</script>
- 現在の許可状態を確認することができる
Notification.permission
というものもあります - 許可状態は
default
(未回答)、granted
(許可済み)、denied
(ブロック)の3つのいずれかが返ります
const permission = Notification.permission;
console.log(permission); // default, granted or denied
通知を送るフェーズ
- 許可を得ると通知を送信できるようになります
- 以前は
new Notification('通知の内容')
でも送信できましたが手元のAndroidではエラーとなり、ちょっとググってみたところこのやり方は非推奨で以下で紹介するServiveWorkerから送るやり方が推奨されるとのことです - メッセージの送信はServiveWorker上で
self.registration.showNotification('通知の内容')
といった感じで送信できます - 以下のコードは動作確認しやすいようにブラウザからServiceWorkerに
postMessage
でメッセージを送り、ServiceWorkerはそれを受け取ってプッシュ通知を送っています
index.html
<button id="send">通知を送信する</button>
<script>
// ServiceWorkerの登録
window.addEventListener('load', () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('sw.js')
.then(registration => console.log('registered', registration))
.catch(error => console.log('error', error));
}
});
// 通知の送信
document.getElementById('send').addEventListener('click', () => {
if (Notification.permission === 'granted') {
navigator.serviceWorker.ready.then(registration => {
registration.active.postMessage('hello!!!');
});
}
});
</script>
sw.js
self.addEventListener('message', function (event) {
self.registration.showNotification(event.data);
});
サンプル
- 上で紹介した記事をベースに作成したサンプルはこちらです
- ソースコードはこちらです
まとめ
- 調べながらだと時間かかりましたが自前でも十分実装できるレベル感ですね
- PushAPIの部分も時間があればまた調べたいと思います