Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
19
Help us understand the problem. What are the problem?

posted at

updated at

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

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の部分も時間があればまた調べたいと思います
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
19
Help us understand the problem. What are the problem?