tmp
Thursday, August 16, 2018
Web Push
GCM だの FCM だの VAPID だのいろいろな実装や情報があってわかりづらいのでまとめ * [GCM/FCMでの実装](https://fiahfy.blogspot.com/2018/08/web-push-gcmfcm.html) * [VAPIDでの実装](https://fiahfy.blogspot.com/2018/08/web-push-vapid.html) * [Firebase Cloud Messaging での実装](https://fiahfy.blogspot.com/2018/08/web-push-firebase-cloud-messaging.html) sample project https://github.com/fiahfy/webpush-sample ## 参考 * https://developers.google.com/web/ilt/pwa/introduction-to-push-notifications * https://developers.google.com/web/fundamentals/codelabs/push-notifications/?hl=ja * http://blog.soushi.me/entry/2017/05/18/124558 * https://firebase.google.com/docs/cloud-messaging/js/client
Web Push (Firebase Cloud Messaging)
Web Push に Firebase Cloud Messaging を利用した場合の実装 ### Set gcm_sender_id Firebase project を作成して `103953800507` (固定値) を指定 ドキュメントではこの固定値を入力するように記載されているが省略しても動作はする(謎) `manifest.json` ``` { : "gcm_sender_id": "103953800507" } ``` ### initialize firebase app Firebase project の設定値を指定 `index.html` ``` ``` `app.js` ``` // Retrieve Firebase Messaging object. const messaging = firebase.messaging() ``` ### register service worker ServiceWorker を `/firebase-messaging-sw.js` とする場合は firebase がよろしくやってくれるので省略可 `app.js` ``` navigator.serviceWorker.register('sw.js') .then((registration) => { messaging.useServiceWorker(registration) }) ``` ### request permission and get token `app.js` ``` messaging.requestPermission() .then(() => { console.log('Notification permission granted.') messaging.getToken() .then((currentToken) => { if (currentToken) { sendTokenToServer(currentToken) } else { // Show permission request. console.log('No Instance ID token available. Request permission to generate one.') // Show permission UI. sendTokenToServer(false) } }) .catch((err) => { console.log('An error occurred while retrieving token. ', err) sendTokenToServer(false) }) }) .catch((err) => { console.log('Unable to get permission to notify.', err) }) ``` ### receive push タブの状態(フォアグラウンド/バックグラウンド)に応じて処理する場所が違うのでそれぞれ実装 #### receive on foreground `app.js` ``` messaging.onMessage((e) => { console.log('Message received. ', e) const title = 'Title' const options = { body: e.data.text } new Notification(title, options) }) ``` #### receive on background `sw.js` ``` // Give the service worker access to Firebase Messaging. // Note that you can only use Firebase Messaging here, other Firebase libraries // are not available in the service worker. importScripts('https://www.gstatic.com/firebasejs/5.3.1/firebase-app.js') importScripts('https://www.gstatic.com/firebasejs/5.3.1/firebase-messaging.js') // Initialize the Firebase app in the service worker by passing in the // messagingSenderId. firebase.initializeApp({ 'messagingSenderId': "
" }) // Retrieve an instance of Firebase Messaging so that it can handle background // messages. const messaging = firebase.messaging() messaging.setBackgroundMessageHandler((e) => { console.log('Message received. ', e) // Customize notification here const title = 'Title' const options = { body: e.data.text } return self.registration.showNotification(title, options) }) ``` ### send push `firebase-admin` を利用、 Firebase の サーバアカウントキーをダウンロードし `key.json` にリネーム `'TOKEN'` に対象の登録トークンを指定 `main.js` ``` const admin = require('firebase-admin') const serviceAccount = require('./key.json') admin.initializeApp({ credential: admin.credential.cert(serviceAccount) }) // See documentation on defining a message payload. const message = { data: { text: 'Here is a payload!' }, token: 'TOKEN' } // Send a message to the device corresponding to the provided // registration token. admin.messaging().send(message) .then((response) => { // Response is a message ID string. console.log('Successfully sent message:', response) }) .catch((error) => { console.log('Error sending message:', error) }) ``` 送信 ``` node main.js ```
Web Push (VAPID)
Web Push に VAPID を利用した場合の実装方法 ### generate VAPID public/private keys `generate_vapid_keys.js` ``` const webPush = require('web-push') const vapidKeys = webPush.generateVAPIDKeys() const keys = { publicKey: vapidKeys.publicKey, privateKey: vapidKeys.privateKey, } console.log(keys) ``` 生成 ``` node generate_vapid_keys.js ``` ### register service worker FCMの場合と変わらず `app.js` ``` navigator.serviceWorker.register('/sw.js') .then((registration) => { swRegistration = registration }) ``` ### subscribe `applicationServerKey` に上記で生成した公開鍵を指定 `app.js` ``` swRegistration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: "PUBLIC_KEY" }) .then((subscription) => { // send subscription to server }) ``` ### receive push FCMの場合と変わらず `sw.js` ``` self.addEventListener('push', (e) => { console.log('[Service Worker] Push Received', e) const title = 'Title' const options = { body: e.data ? e.data.text() : 'Empty payload' } e.waitUntil(self.registration.showNotification(title, options)) }) ``` ### send push 暗号化周りが面倒なので `web-push` を利用 `'PUBLIC_KEY'`, `'PRIVATE_KEY'` にそれぞれ生成した公開鍵/秘密鍵を指定 `'SUBSCRIPTION'` は購読時に取得したものを指定 `main.js` ``` const webPush = require('web-push') const payload = 'Here is a payload!' const options = { vapidDetails: { subject: 'mailto:example_email@example.com', publicKey: 'PUBLIC_KEY', privateKey: 'PRIVATE_KEY' }, TTL: 60 } webPush.sendNotification( 'SUBSCRIPTION', payload, options ) ``` 送信 ``` node main.js ```
Web Push (GCM/FCM)
送信のみにFCMを利用した場合の実装方法 Firefox のみの話でいうと FCM を利用しないためFCM周りの設定は省略できる (Chromeを考えると必須ではあるが) ### Set gcm_sender_id Firebase project を作成して `送信者 ID` を指定 `manifest.json` ``` { : "gcm_sender_id": "SENDER_ID" } ``` ### register service worker `app.js` ``` navigator.serviceWorker.register('/sw.js') .then((registration) => { swRegistration = registration }) ``` ### subscribe `app.js` ``` swRegistration.pushManager.subscribe({ userVisibleOnly: true }) .then((subscription) => { // send subscription to server }) ``` `userVisibleOnly` は現状必須だが Firefox だと省略できる ### receive push `sw.js` ``` self.addEventListener('push', (e) => { console.log('[Service Worker] Push Received', e) const title = 'Title' const options = { body: e.data ? e.data.text() : 'Empty payload' } e.waitUntil(self.registration.showNotification(title, options)) }) ``` ### send push #### without data payloads ペイロードなしの通知は endpoint と サーバーキーの指定のみで送信できる サーバーキー は Firebase project に記載されているものを使用 ``` curl "END_POINT" --request POST --header "TTL: 60" --header "Content-Length: 0" --header "Authorization: key=SERVER_KEY" ``` #### with data payloads ペイロードありの通知は暗号化周りが面倒なので `web-push` を利用 `'SUBSCRIPTION'` は購読時に取得したものを指定 `main.js` ``` const webPush = require('web-push') const payload = 'Here is a payload!' const options = { gcmAPIKey: 'SERVER_KEY', TTL: 60 }; webPush.sendNotification( 'SUBSCRIPTION', payload, options ) ``` 送信 ``` node main.js ```
Newer Posts
Older Posts
Home
Subscribe to:
Posts (Atom)