メインコンテンツまでスキップ

「webpush」タグの記事が2件件あります

全てのタグを見る

Webプッシュ通知についてブラウザ間の挙動の違いを調べてみた(フロントエンド編)

箕浦
箕浦
開発二部

こんにちは。開発 2 部 箕浦です。
現在、関わっている案件でWebプッシュ通知について調べる機会がありましたので
実装の仕方からブラウザ間の挙動の違いを調査した結果を紹介します。
本記事は、後編であるフロントエンド編になります。

今回はフロントエンドはReactで実装します。

Service Worker

Webプッシュ通知は、ユーザーがウェブサイトを見ている状態だけでなく、他のサイトを見ているときや、別のアプリケーションを動かしているときなどにも通知されてほしいです。
WebアプリケーションはReact(Javascript)でブラウザ上で動作するものなので、基本的にはユーザーがウェブサイトを閲覧していないときは動作しません。
そのため、Webプッシュ通知を受け取ったときの動作は、本体のWebアプリケーションとは別のプロセスで動かしておいて、プッシュ通知の処理を行う仕組みが必要となります。
その役割を担うのがService Workerです。
Service Workerは、プッシュ通知だけでなく、バックグラウンドで何か処理をさせたいときなど用途はいろいろあります。
ただし、ブラウザの種類やバージョンにより、サポート状況や挙動が変わることがありますので事前に動作確認が必要となります。

publicフォルダ配下に以下の service-worker.js ファイルを作成します。 簡単に説明すると、
push イベントに対して、タイトルやメッセージなどを受け取り、 showNotification を使って、デスクトップにプッシュ通知を表示します。
notificationclick イベントに対して、通知がクリックされた際に、指定したURLへ遷移するようにしています。

service-worker.js
addEventListener('push', (event) => {
console.log('[Service Worker] Push Received.');
console.log(`[Service Worker] Push had this data: "${event}"`);

if (!(self.Notification && self.Notification.permission === 'granted'))
return;

var data = {};
if (event.data)
data = event.data.json();

console.log(data)

self.clients.matchAll().then(clients => {
clients.forEach(client => {
client.postMessage({
data: data
});
});
});

var title = data.data['pinpoint.notification.title'];
var message = data.data['pinpoint.notification.body'];
var icon = data.data['pinpoint.notification.imageIconUrl'];
var image = data.data['pinpoint.notification.imageUrl'];
var options = {
body: message,
icon: icon,
image: image,
data: data,
};
event.waitUntil(self.registration.showNotification(title, options));
});

addEventListener('notificationclick', (event) => {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.data['pinpoint.url'])
);
});

React

React側ではまず、firebase のライブラリをインストールします。

npm install firebase

App.jsに前編でFirebaseコンソールからコピーしたコードスニペットをそのまま貼り付けます。

src/App.js
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";

const firebaseConfig = {
apiKey: "APIキー",
authDomain: "webpush-c7bed.firebaseapp.com",
databaseURL: "https://webpush-c7bed.firebaseio.com",
projectId: "webpush-c7bed",
storageBucket: "webpush-c7bed.appspot.com",
messagingSenderId: "586895317040",
appId: "アプリ ID",
measurementId: "G-SPL1GEMWDJ"
};

const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);

同じく、以下のコードを追記します。
「サーバーキー」には、前編でFirebaseコンソールからコピーしたサーバーキーを設定します。
今回はサーバーキーや上記の設定は、ソースコードにハードコーディングしていますが、本番環境で使用する場合は、外から読み込むなどの仕組みが必要です。

src/App.js
import { getMessaging, getToken, isSupported } from "firebase/messaging";
const messaging = getMessaging(app);

const vapidKey = "サーバーキー"
var registeredServiceWorker;
navigator.serviceWorker.register('/service-worker.js').then((reg) => registeredServiceWorker = reg)

function App() {

useEffect(() => {

function requestPermission() {
isSupported().then((isSupport) => {
if (!isSupport) {
console.log('Messaging is not support.');
return
}

console.log('Requesting permission...');
Notification.requestPermission().then((permission) => {
if (permission === 'granted') {
console.log('Notification permission granted.');
getTokenRequest()
}
})
})
}

async function getTokenRequest() {
// Add the public key generated from the console here.
getToken(messaging, {
vapidKey: vapidKey,
serviceWorkerRegistration: registeredServiceWorker
})
.then((currentToken) => {
if (currentToken) {
// Send the token to your server and update the UI if necessary
// ...
console.log(`token: ${currentToken}`);
// ここで取得したトークンをサーバーへ送信する
} else {
// Show permission request UI
console.log('No registration token available. Request permission to generate one.');
// ...
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
// ...
});
}
requestPermission();
}, []);

return (
<div className="App">
<div>
・・・
</div>
</div>
);
}

ここまでで実装は完了です。

プッシュ通知の送信

フロントエンドをローカルで起動します。

npm run start

ブラウザが起動すると、画面上部にプッシュ通知を許可もしくはブロックするがポップアップで表示されます。
ここで許可を選択しておきます。
ブロックを選択すると、プッシュ通知が届かなくなります。

permission

すると、トークンが払い出されます。 今回はわかりやすいようにトークンをデバッグコンソールに出力しています。

token

本来であれば、このトークンをサーバーへ何らかの方法で送り、サーバー側でユーザーと紐づけて管理しておきます。
今回はサーバーは省略しているので、このトークンをコピペすることにします。

今回はプッシュ通知の送信は簡単に確認するため、Amazon Pinpointのコンソール画面から送信します。
デバイストークンには先ほどコピーしたトークン
プッシュ通知サービスには「FCM」
を入力し、メッセージの内容を入れて、プッシュ通知を送信します。

pinpoint_1 pinpoint_2

送信を行うと、デスクトップの右下に無事プッシュ通知が表示されました!!

push-disp

ブラウザによる挙動

ここからは、ブラウザによるプッシュ通知の挙動を確認していきます。
今回はChrome、Edge、FireFoxの3種類で確認することにします。

デフォルトの状態でのプッシュ通知の表示

まずはデフォルトの状態でのプッシュ通知の表示は、

Chromeの場合

push-disp

Edgeの場合

push-edge

Firefoxの場合

push-firefox

こちらは、同じ結果となりました。

requireInteractionを有効

ユーザーがクリックするか閉じるかするまで、通知が自動的に閉じずに残る設定である requireInteraction を有効にした場合、

Chromeの場合

push-crome-with-button

Edgeの場合

push-edge

Firefoxの場合

push-firefox-with-button

こちらは、Edgeの場合は「閉じる」ボタンが表示されず、25秒ほどで通知の表示が消えました。 Edgeの場合、requireInteractionの設定だけではだめなようです。

プッシュ通知を閉じずに、連続して何回か送信した場合

プッシュ通知の「閉じる」ボタンを押さずに、連続して何回か送信した場合の動作を見てみます。

Chromeの場合

push-crome-with-button-3

Edgeの場合

push-edge

Firefoxの場合

push-firefox-with-button-3

ChromeとFirefoxでは、連続して送ると、3つまではデスクトップに表示されますが、それ以降は、 デスクトップに表示せず、通知管理に溜まっていく動作となっていました。
その状態で閉じるボタンで通知を閉じると通知管理に溜まっていたものが、 順番に表示されます。
Edgeでは、通知管理には溜まっていきますが、どれだけ送っても、デスクトップには1つまでの表示となっています。

ブラウザを起動していない状態でのプッシュ通知

ChromeとFirefoxでは、即時に通知表示されず、ブラウザを開いて、20秒ほど待っていると、 それまで溜まっていたものが一度に通知されてくる動作となっています。
それに対し、Edgeでは、ブラウザを起動していない状態でも、プッシュ通知が表示されました。

ブラウザによって、プッシュ通知のサポート状況や、実装は以後のバージョンアップで動作は変わる可能性がありますが、 現時点ではこのような差異がありました。
他にもいろいろな設定がありますので、今後も色々触ってみようと思います。

Webプッシュ通知についてブラウザ間の挙動の違いを調べてみた(バックエンド設定編)

箕浦
箕浦
開発二部

こんにちは。開発 2 部 箕浦です。
現在、関わっている案件でWebプッシュ通知について調べる機会がありましたので
実装の仕方からブラウザ間の挙動の違いを調査した結果を紹介します。
本記事は、前編であるバックエンド設定編になります。

Webプッシュ通知とは

Webプッシュ通知とは、ウェブサイトからユーザーに対して通知を送信する仕組みです。
画像のようにウェブサイトにアクセスした際、通知の許可を求めるポップアップで「許可」を選択し、
デスクトップ右下にポップアップされるあれのことです。
ブラウザがサポートしている場合、ユーザーはウェブサイトから通知を受け取ることができます。

iOS16.4から既にサポートされており、iPhoneでもWebプッシュを受けれるようになっています。

webpush-permission

webpush

Webプッシュ通知を実装するには、バックエンド側の実装が必要になるのですが、Webプッシュといってもいろいろな方法があり、サービスも複数あります。

今回は、簡単に、Firebase Cloud Messaging と Amazon Pinpoint というサービスを組み合わせて実装します。 Firebase Cloud Messaging だけでもWebプッシュは可能ですが、管理コンソール画面からプッシュ送信することを考え、Amazon Pinpointの管理コンソールからの方が送りやすいため、Amazon Pinpointを組み合わせました。

さらに、今回は詳しく取り上げませんが、Amazon Pinpointを利用すると、ある特定のユーザグループのみWebプッシュを送信するという使い方ができますので、特定の地域に住む人のみとか、特定の年齢層の人のみにWebプッシュを送信するといったことも可能です。

Firebase

まずは、Firebase にプロジェクトを作成します。 Firebase を利用するにはGoogleアカウントが必要になります。

firebase-project

続いて、上記で作成したプロジェクトにウェブアプリを追加します。 今回は下のようなアプリを作成しました。

firebase-webapp

下の方の「SDKの設定と構成」の欄にnpm、CDN、Configでそれぞれ実装するときのコードスニペットが表示されていますので、フロント側にこれを組み込みます。
今回はReactで実装しますので、npmを選択します。

firebase-config

また、「Cloud Messaging」タブでAPIが有効になっていることを確認し、 「サーバーキー」もメモっておきます。

firebase-serverkey

Firebase Cloud Messagingの設定は以上です。

Amazon Pinpoint

つづいて、Amazon Pinpointの管理コンソールに入り、
こちらもプロジェクトを適当に作成し、 プッシュ通知の設定にてFirebase Cloud Messaging (FCM)の キー認証情報のAPIキーの欄に先ほどメモした「サーバーキー」を設定します。

pinpoint-config

Amazon Pinpointの設定は以上です。簡単ですね。

次回の記事では、フロント側の実装方法について解説し、実際の挙動を確認します。

お楽しみに!