3
1

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 1 year has passed since last update.

AmplifyのAnalytics(Amazon Pinpoint)を使ってWebプッシュ

Posted at

iOSの16.4からWebプッシュに対応しました。

AWSのブログでも紹介されていた記事を参考にAmplifyで作成したアプリでWebプッシュを試してみました。

詳細な手順は個人ブログで紹介しています。

https://moritalous.pages.dev/amplify/web-push

Firebaseプロジェクトの作成

「AmplifyでWebプッシュ」といってますが、AmplifyやPinpoint単体では通知を行うことはできず、通知には外部サービスに頼る必要があります。
Firebase Cloud Messagingを使用すると、PinpointからはAndroidにプッシュする感覚でWebプッシュが行なえます。

Firebase consoleでプロジェクトを作成し、Firebase Cloud Messagingを有効化します。

Firebaseプロジェクトの作成を参考になんやかんや設定をして、以下の3点を入手します。

  • SDK の設定と構成のConfig
  • サーバーキー
  • 鍵ペア

AmplifyのAuthとAnalyticsを追加

amplify add auth
amplify add analytics
amplify push

このサクサク感、病みつきになりますよね

Amazon PinpointにFirebase Messagingのキーを登録

マネジメントコンソールを使用しないといけないのが残念ですが我慢しましょう。Firebase Cloud Messagingで取得したサーバーキーを登録します。

image.png

Service Workerを作成

Webプッシュを受けるのはService Workerです。
pushnotificationclickのイベントリスナーを用意します。

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)

  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) => {
  console.log('[Service Worker] Notification click: ', event);
  event.notification.close();
  event.waitUntil(
    clients.openWindow(event.notification.data.data['pinpoint.url'])
  );
});

Appのコードを準備

Firebase Cloud Messagingの初期化

import { initializeApp } from "firebase/app";
import { getMessaging } from "firebase/messaging";

const firebaseConfig = {
  apiKey: "AIzaSyDjcpgUOkQKYsfahsBx-pd5rRNLMu8e2OI",
  authDomain: "webpush-6b963.firebaseapp.com",
  projectId: "webpush-6b963",
  storageBucket: "webpush-6b963.appspot.com",
  messagingSenderId: "849385313410",
  appId: "1:849385313410:web:75afe5212cc8a264da109b"
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Initialize Firebase Cloud Messaging and get a reference to the service
const messaging = getMessaging(app);

鍵ペアの定義

const vapidKey = "BCYBsbttg4lKsLkSz3KXHdoijEKJhLWj7Au69Sp9niUUa_IwRtXAYSd7zLP52hBKG-_uf8evUTVphiMKl4CNihk"

Service Workerの登録

import { ServiceWorker } from 'aws-amplify';

const serviceWorker = new ServiceWorker()
var registration: ServiceWorkerRegistration;
serviceWorker.register('/service-worker.js', '/').then((reg => registration = reg as ServiceWorkerRegistration))

AmplifyとFirebaseのキメラ感がすごい

権限の許可を要求

こんなやつを出します。

image.png

import { getToken } from "firebase/messaging";

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()
    }
  })
})
}

デバイストークンの取得

公開鍵からデバイスごとのトークンを生成します。

import { getToken } from "firebase/messaging";

function getTokenRequest() {
  // Add the public key generated from the console here.
  getToken(messaging, {
    vapidKey: vapidKey,
    serviceWorkerRegistration: registration
  })
    .then((currentToken) => {
      if (currentToken) {
        // Send the token to your server and update the UI if necessary
        // ...
        console.log(`token: ${currentToken}`);

        setDeviceToken(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);
      // ...
    });
}

デバイストークンをAmazon Pinpointに登録

import { Analytics } from 'aws-amplify';

Analytics.updateEndpoint({
  address: deviceToken,
  channelType: "GCM",
  optOut: 'NONE',
}).then((reason => { console.log(reason) }))

通知を送信

1:1で送信するケース

サーバー側で長時間処理をして、処理完了を通知したいケースです。この場合は、PinpointのsendMessages APIを使用します。

body.tokenがデバイストークンです。

await sleep(5000)

const params = {
ApplicationId: applicationId,
MessageRequest: {
  "Addresses": {
    [body.token]: {
      "ChannelType": "GCM"
    }
  },
  "Endpoints": {},
  "MessageConfiguration": {
    "GCMMessage": {
      "Title": "Push Title",
      "Action": "URL",
      "Body": "Body Message",
      "ImageUrl": "https://placekitten.com/200/300",
      "ImageIconUrl": "https://placekitten.com/g/96/96",
      "Url": body.url || 'http://localhost:8080'
    }
  }
}
}

const res = await pinpoint.sendMessages(params).promise()

通知が来ました。

image.png

キャンペーンの通知

多数に一斉に通知をしたい場合はこちらのケース。
セグメントを作成し、キャンペーンとして通知します。

image.png

image.png

iPhoneへの通知

さて、iPhoneへの通知については1つ注意点があり、ユーザーがPWAとしてインストールする必要があります
ます。

PWAとしてインストールした状態で通知を受信することができました。

image.png

詳細な手順は個人ブログで紹介しています。

https://moritalous.pages.dev/amplify/web-push

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?