35
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PWAAdvent Calendar 2020

Day 5

[PWA]プッシュ通知を実現するPushAPIとNotificationAPI

Last updated at Posted at 2020-12-04

Webアプリにおけるプッシュ通知

  • PWAを代表する機能としてプッシュ通知があげられることがよくあると思います(iPhone/Safariだとまだ使えないんですがね)
  • Webアプリにおけるプッシュ通知はPushAPINotificationAPIというの2つの仕組みからなっています

スクリーンショット 2020-12-05 2.36.19.png
Screenshot_20201205-023648.png

PushAPI

  • PushAPIはサーバからの通知を受け取ることができるAPIです

NotificationAPI

  • NotificationAPIはユーザに対して通知を送ることができるAPIです

一連の流れ

  • Webアプリにおけるプッシュ通知送信までの一連の流れは、PushAPIがサーバからの通知を受け取り、NotificationAPIを呼び出してユーザに通知を送ります

スクリーンショット 2020-12-05 2.12.54.png

  • それぞれの使い方を整理しようと思いましたが思いの外大変だったので今回はNotificationAPIを紹介します

NotificationAPIの使い方

  • NotificationAPIはユーザに通知を送るAPIでした
  • 通知を送るためには事前に許可を得る必要があります
    • 見た瞬間に拒否を押してしまうあれですね・・・(許可を得るタイミングはよく考えて実装しましょう!)

スクリーンショット 2020-12-05 2.16.03.png

  • というわけで許可をとるフェーズ通知を送るフェーズの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の部分も時間があればまた調べたいと思います
35
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?