はじめに
こんにちは
エンジニアの taptappun です
私はこれまでにPush通知の導入・実装・運用を数多く行ってきました
今回、その中で培った知見を共有したいと思います
これからPush通知の導入を検討している方々へ参考になればと思います
Push通知概論
情報伝達の種類
ネットワークを介してユーザに情報を伝達する方法は主に3種類の方法に分類されます
型名 | 説明 | 例 |
---|---|---|
Pull型 | ユーザがサーバから情報を取得する方法 | Webサイト、ネイティブアプリなど |
Push型 | サーバがユーザに情報を伝達する方法 | Push通知、メール配信など |
双方向 | Push型、Pull型両方を用いて情報を伝達する方法 | チャット、電話など |
今回解説している「Push通知」はPush型の情報伝達の方法になります
なおPull型、Push型はマーケティング用語としても用いられています
参考
Pull型
ユーザ(端末)がサーバ(サービス)にアプローチすることで情報を取得する方法をPull型といいます。Webサイト(Webサービス)の運営などはPull型にあたります
ほとんどのWebサービスでは伝達手段はPull型のみを用いているため、ユーザに利用してもらうことでのみユーザに情報を伝達することができ、Webサービスからユーザに情報を伝達するとことができません
Push型
サーバ(サービス)からユーザ(端末)へ情報を伝達する方法をPush型といいます
今回解説する「Push通知」もPush型の伝達方法になります
Push型および「Push通知」が行われる概要を以下に図示します
※図の中に出てきた用語について以下に解説します
- Push通知Token: Push通知を送信するために必要なユーザ(端末)と紐づいた一意な文字列
- AppServer: アプリケーションの配信を行っている(Push通知を配信するための)サーバ
- Firebase/Apple(Web) Push Server: Android端末であればFirebaseのサーバ(Firebase Cloud Messaging:FCM)、iOS端末であればAppleのサーバ(Apple Push Notification Service:APNs)
Push通知を導入する効果
Push通知を導入する意義、Push通知を導入するにあたり気をつけること、Push通知の導入に対する要件を考える時に考え方などについて説明します
メリット
- アクティブユーザ(サービスを利用してくれているユーザ)の増加
- Push通知を受信するとユーザはその通知を確認し、サービスにアクセスするようになります。これによりオフライン状態のユーザや長期間利用していないユーザ(休眠ユーザ)が利用してくれるようになります
デメリット
- Push通知の配信が多すぎると逆にユーザの離脱要因になる
- Push通知が多すぎると通知を切られたり、アプリをアンインストールされてしまったりと逆にユーザが利用してくれなくなってしまう要因となります
留意点
- 配信の即時性はベストエフォート
- Push通知を配信したら「すぐに」「必ず」ユーザに通知が届くことを保証してくれてはいません。あくまでPush通知はベストエフォートで配信されます(例えば端末の電源が長時間OFFになっていたり場合、Push通知をユーザに届けることができず通知が削除されてしまい通知されないといったケースも存在します)
参考
Push通知の種類と補足
- ネイティブアプリ(Android/iOS)へのPush通知
- AndroidのPush通知
- iOSのPush通知
- Web Push(ブラウザへのPush通知)
- ネイティブアプリへのPush通知とは概要やフローが異なるものとなります。今回は触れません
- ローカル通知
AndroidのPush通知
Android端末にPush通知を行う場合に限りPush通知を受け取ってもユーザに受け取ったことを「通知」しないということもできます(つまりサーバから端末に対してデータだけを送ることもでます)
iOSのPush通知
iOS端末にPush通知を行う場合には必ずユーザに「通知」しなければなりません(つまりAndroidのようにサーバからデータだけを送るということはできない)
ローカル通知
サーバを介さないで端末内から通知を行う方法を ローカル通知
といいます
Push通知とは異なる特徴として
- 端末がオフラインであってもユーザへ通知することができる
- サーバに負荷がかからない(Push通知の配信のためにサーバを介すことがないため)
という特徴があります
ローカル通知とPush通知
ローカル通知を用いることによってサーバへの負荷が軽減されるため、Push通知とローカル通知の両方を使用することによってPush通知配信時へのサーバへの負荷を軽減することができます
ローカル通知とPush通知を両方を使用する場合の要件と実装方針の例
要件: イベントの開始時刻になったら通知してお知らせしたい
実装方法: イベント開始時刻の情報をユーザが事前に取得し、時間になったらローカル通知で通知を行う
このように ローカル通知とPush通知の両方を使用することによりサーバへの負荷を軽減した運用を行うことができます
Push通知の導入
Push通知の機能を実際に導入していくまでの流れや実装にあたり行う必要がある作業の内容について以降に紹介していきます
Android/iOS共通のワークフロー
Push通知を行うためにはAndroidではFirebaseのサーバ(Firebase Cloud Messaging:FCM)を使用して送信する必要があり、iOSではAppleのサーバ(Apple Push Notification Service: APNs)を使用して送信する必要があります
Push通知が実際に配信されるまでの処理の流れはAndroid、iOS共にほぼ共通しています。以下に処理の流れを示します
Androidへの導入手順
AndroidにPush通知を導入する手順の概要
AndroidのPush通知の設定方法はFCM(Firebase Cloud Messaging)の設定と同様に行っていくことで設定できます
以下の手順で実装していきます
1. FirebaseのプロジェクトにFCMを開始する
すでにFCMを開始している場合には「プロジェクトの設定」を開き「アプリを追加」を選択することでFCMにて配信するプラットフォームの追加を行うことができます
2. FCMの開始のために開発しているAndroidの情報を記入する
3. Push通知を受け取るためのFCMの設定情報が記述されたファイルを導入する
google-services.json
というファイルをダウンロードしてきてAndroidプロジェクトの特定の場所(以下のように プロジェクトルート/app/google-services.json
となるような場所)に設置します
4. FCMの実装手順に合わせてAndroidの実装
AndroidプロジェクトにてFCMを使用するための各種ライブラリをインストールしていきます(以下のように詳細な手順が表示されます)
5. Push通知Tokenを取得して記録する
AndroidにてFirebaseのライブラリが導入できている状態で以下のような処理を追加することによってPush通知Tokenを取得できます
FirebaseMessaging.getInstance().token
.addOnCompleteListener(OnCompleteListener { task ->
if (!task.isSuccessful) {
return@OnCompleteListener
}
// Push通知Token
val pushToken = task.result
})
上記の val pushToken
の値をサーバに送信し、記録します
6. アプリIDやPush通知Tokenなどの必要な情報を付与してFCMのAPIに送る
サーバよりPush通知を送るために必要な情報であるFirebaseのアプリIDはプロジェクト設定より確認できる
このアプリIDやPush通知Tokenなどの必要な情報を用いてFirebase Cloud Messaging APIを実行してPush通知を送信する
7. 対象のPush通知Tokenの端末にPush通知が届く
Push通知を受信したら通知した内容が表示される
iOSへの導入手順
iOSにPush通知を導入するためには Apple Developer Program (登録には年間登録料は99$を支払う必要がある) に登録する必要があります
Apple Developer Program に登録しなかった場合以降の証明書の作成などの画面に遷移することができません
またAppストアにすでにiOSアプリを配信している場合とこれから配信している場合とでは設定していく手順が異なります
以降ではすでにAppストアにiOSアプリが配信されている状態でのPush通知の導入手順を紹介していきます
1. Push通知の使用を有効にする
ストアに配信した物を含めた、すでに作成されている Identifiers を確認し、対象の Identifer
を選択します
Identifer
の詳細の中から Push Notification
の部分が有効になっているかどうか確認します。有効になっていなかったら Push Notification
を有効にした Identifer
を作成します
2. APNs用証明書(.cer)の作成
Certificates にアクセスして新しくPush通知用の証明書の作成を行っていきます
Push通知を配信用の証明書の種類を選択します
※以降ではアプリストアに配信可能な権限をもつ人にのみ選択、設定を行うことができます
Identifers
の中から対応したい App ID を確認し、選択して、Continueを選択します
CSR(Certificate Signing Request)ファイル
をアップロードしてContinueを選択します
これでAPNs用証明書(.cer) が作成されるのでcerファイルをダウンロードしておきます
CSRファイルの作り方
以降では途中でアップロードする必要があった CSRファイル
の作り方を紹介します
キーチェーンアクセスを開き
「キーチェーンアクセス」>「証明書アシスタント」>「認証局に証明書を要求」を選択します
メールアドレスを入力して「続ける」を選択します
鍵のサイズなどはそのままで「続ける」を選択します
これで CSRファイル
が作成されます。この CSRファイル
をアップロードして用いるようにしてください
3. APNs用証明書(.p12) の作成
ダウンロードした APNs用証明書(.cer) ファイルを開くと キーチェーンアクセス が起動して証明書が読み込まれます
読み込んだ証明書を選択して「書き出す」を選択して書き出しを行います
フォーマットを 個人情報交換(.p12)
を選択して保存することでAPNs用証明書(.p12)ファイルとして保存します
※ FCM(Firebase Cloud Messaging)やAmazon PinpointなどのSaaSを用いる場合、cerファイル
と p12ファイル
をアップロードして設定すればpush通知の設定を行うことができます
4. p12ファイルからpemファイルに変換する
書き出した p12ファイル をOpenSSLコマンドを使用してpemファイルへと変換を行います
openssl pkcs12 -in **.p12 -out **.pem -nodes -clcerts
この変換した pemファイル
と cerファイル
をPush通知を配信するサーバに設置します
5. deviceTokenを取得して記録する
Swift
にて以下のような処理を記述後、iOSアプリ向けにビルドを行います
ビルドしたiOSアプリを実行することでその端末に紐づいたdeviceToken(iOSでのPush通知Token)が取得できるようになります
import UIKit
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// ① プッシュ通知の利用許可のリクエスト送信
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
guard granted else { return }
DispatchQueue.main.async {
// ② プッシュ通知利用の登録
UIApplication.shared.registerForRemoteNotifications()
}
}
return true
}
}
extension AppDelegate {
// ③ プッシュ通知の利用登録が成功した場合
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%.2hhx", $0) }.joined()
print("Device token: \(token)")
}
// ④ プッシュ通知の利用登録が失敗した場合
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register to APNs: \(error)")
}
}
上記の let token
の値をPush通知配信サーバに送ってその値を記録します
6. APNs証明書ファイルやdeviceTokenなどの必要な情報を付与してAPNsのAPIに送る
APNsのAPIへの実行方法の詳細についてはこちらに記載されています Sending Notification Requests to APNs
以下のようなBashコマンドを用いて実行することでPush通知を送信することができます
#!/bin/bash
CERTIFICATE_FILE_NAME=**.cer
CERTIFICATE_KEY_FILE_NAME=**.pem
TOPIC=com.example.MyApp
DEVICE_TOKEN=<Your device token>
APNS_HOST_NAME=api.sandbox.push.apple.com
curl -v --header "apns-topic: ${TOPIC}" --header "apns-push-type: alert" --cert "${CERTIFICATE_FILE_NAME}" --cert-type DER --key "${CERTIFICATE_KEY_FILE_NAME}" --key-type PEM --data '{"aps":{"alert":"test"}}' --http2 https://${APNS_HOST_NAME}/3/device/${DEVICE_TOKEN}
この時に参照している **.cer
と **.pem
はそれぞれ 2. APNs用証明書(.cer)の作成 と 4. p12ファイルからpemファイルに変換する で取得したファイルを参照しています
7. 対象のdeviceTokenの端末にPush通知が届く
Push通知を受信したら通知が表示されるようになります
参考
- Sending Notification Requests to APNs
- プッシュ通知に必要な証明書の作り方2022
- [iOS]コマンドラインからPush通知を送る
- iOS13におけるプッシュ通知に必要なデバイストークンの取得方法
他
Push通知配信SaaSについて
Push通知を運用していく中でよく起こる困りごと
- Push通知の配信に時間がかかる
- Push通知を配信するユーザ数が多くなれば処理の実行時間が長くなりユーザに通知が届くまでに時間がかかってしまう
- Push通知配信時のサーバへの負荷が大きい(長時間バッチ処理を実行している状態であるため、CPU使用率やメモリ使用量が大きくなる)
FCM(Firebase Cloud Messaging)やAmazon PinpointなどのSaaSを用いることでこのような問題の解決に役立ちます
Push通知のためのSaaSを追加すると以下のようなフローにてPush通知が配信されます
FCM(Firebase Cloud Messaging)
FCMのアーキテクチャの概要
FCMについて
- AndroidのPush通知を行うためには必須
- iOSへのPush通知の他にもWeb PushへのPush通知もサポートしている
- 料金は無制限で無料→Firebase Priceing
- Firebaseのコンソール画面からもPush通知を送信できる
- セグメントPush(送る対象を絞ってPush通知を配信する機能)にも対応(セグメント対象は
Firebase Analytics
で収集されているデータが基になる)
その他、仕様や制約についてはFCMメッセージについてを参照
FCMのiOSでの設定方法
Androidの設定方法はAndroidへの導入手順 にて説明したため省力します
ここではiOSの設定方法を紹介していきます
1. FCMにて新しくiOS向けに実装を開始する
Android の時と同様にiOSも設定していきます
2. FCMでiOSアプリの情報を入力する
3. iOSにFCM用の情報の設置
4. iOSのサーバ用の追加設定
plistファイル
の設定を行ったらiOSの場合、APNsへの登録が必要になります。FIrebaseでは各種APNs証明書などの取得が完了したらその情報を以下のように設定する必要があります
5. FCMのAPIよりPush通知を送信する
4.
のAPNsの設定まで完了したらAndroidと同様にFirebaseのコンソールまたはFirebase Cloud Messaging APIを実行することでPush通知を送信することができます
Amazon Pinpoint
Amazon Pinpointについて
- SMS、Eメール、Push通知、アプリ内メッセージ、音声など、さまざまな方法でPush型の情報伝達を行うことができます(Push通知はその中の一つ)
- Web Pushには非対応
- 通知 100 万件までは無料。その後は通知 100 万件あたり 1 USD の料金が発生。詳しくはAmazon Pinpointの料金より
Amazon PinpointでのPush通知の設定方法
Amazon PinpointにてAndroid/iOSのPush通知の実装・設定を行なっていく様子を説明していきます
1.Amazon PinpointにてPush通知の設定を開始する
2.Amazon Pinpoint Androidの設定を行う
セットアップ画面にてAndroidのタブを選択してAPIキーなどを設定します
ここで設定するAPIキーの値は上記のAndroidへの導入手順よりFIrebaseの設定画面より確認できます
3. Amazon Pinpoint iOSの設定を行う
セットアップ画面にてAPNsのタブを選択して証明書や署名鍵などのファイルを設定をアップロードします
ここで設定する証明書や署名鍵などの取得方法について上記のiOSへの導入手順にて取得したものを用います
4. Amazon Pinpointを使ってPush通知を配信する
Amazon PinpointでのPush通知の配信方法は2種類あります
- Amazon Pinpointのコンソール画面よりPush通知を配信する
- AWS SDKを用いて設定しPush通知を配信する
AWS SDK での Amazon Pinpoint の使用
それぞれ用途に合わせた配信方法を用いることによってAmazon PinpointからPush通知を端末に向けて配信することができます
その他Push通知にまつわる色々な質問について
- Q: 送ったPush通知を見てどれだけのユーザがアクセスしてくれたのか知りたい
- A: Push通知配信サービスのコンソール画面からある程度、確認することができます。Firebaseのコンソール画面においては以下のように表示されます。(AWS Pinpointにも似たようなコンソール画面が存在します)またこのAPNs単体で使用している場合では開封率などを確認することができません。そのような場合においてはアプリの中に開封などが行われたかどうかのトラッキング処理を埋め込むことによって確認することができます
- A: Push通知配信サービスのコンソール画面からある程度、確認することができます。Firebaseのコンソール画面においては以下のように表示されます。(AWS Pinpointにも似たようなコンソール画面が存在します)またこのAPNs単体で使用している場合では開封率などを確認することができません。そのような場合においてはアプリの中に開封などが行われたかどうかのトラッキング処理を埋め込むことによって確認することができます
- Q: Push通知がユーザに届かないことはあるのか?
- A: 存続期間を過ぎても配信が完了できなければ取りこぼしが発生する場合があります。詳しくは メッセージの存続期間の設定 や Sending Notification Requests to APNs を参照ください
- Q: Push通知を切っているユーザのPush通知Tokenを削除できるようにしたい
- A: Push通知を切ったという情報がサーバに自動的に送られるくるようなことはありません。そのためユーザからPush通知を切ったことがわかるような情報を送ってもらうことで判別することができます
まとめ
Push通知がどういったものなのかおおよそ内容について紹介しました
またPush通知の実装方法やツールの比較についての大まかな流れについても紹介しました
Push通知の導入や運用を検討するにあたり参考となりましたら幸いです