2021/05/19
Firebase Cloud Messagingを使ってiOSアプリにPush通知を送る
Firebaseの公式ドキュメントをみて対応しました。
対応手順
- Apple Developerアカウントにログインして、APNsのキーを作成して
p8
ファイルをダウンロードします - Apple Developerアカウントにて、開発用及び本番環境用のAPNs証明書を作成します。
- 上記をFirebaseコンソール上で プロジェクトを設定 > Cloud Messaging のメニューから先程ダウンロードした
APNs 認証キー
及びAPNs証明書
をアップロードします。 - firebase-ios-sdkをインストールして
Messaging
を使えるようにします。 - XCode上で、TARGETS > YOURAPP > Signing & Capabilitiesで
Push Notifications
のCapabilityを追加します。 - AppDelegateに以下の記述を追加します。
import SwiftUI
import Firebase
@main
struct Application: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate, MessagingDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: { granted, _ in
if granted {
// TODO subscribe to fcm topic, etc...
}
}
)
} else {
let settings: UIUserNotificationSettings
= UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Oh no! Failed to register for remote notifications with error \(error)")
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
var readableToken: String = ""
for i in 0..<deviceToken.count {
readableToken += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
}
print("Received an APNs device token: \(readableToken)")
}
}
extension AppDelegate: MessagingDelegate {
@objc func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase token: \(String(describing: fcmToken))")
// let dataDict:[String: String] = ["token": fcmToken ?? ""]
// NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
}
}
extension AppDelegate : UNUserNotificationCenterDelegate {
func userNotificationCenter(
_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void
) {
if #available(iOS 14, *) {
completionHandler([[.banner, .list, .sound]])
} else {
completionHandler([[.alert, .sound]])
}
}
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification.request.content.userInfo
// 以下の用にしてnotification centerを使って通知し、
// view側では以下のメソッドを使って、処理を続行します。
// onReceive(NotificationCenter.default.publisher(for: Notification.Name("didReceiveRemoteNotification")))
NotificationCenter.default.post(
name: Notification.Name("didReceiveRemoteNotification"),
object: nil,
userInfo: userInfo
)
completionHandler()
}
}
FCMをDebugする
Push通知が届かない時の確認手順です。
- Simulator上で通知の表示を確認する
- 直接APNsを呼び出してみて確認する
- Firebaseコンソールからテストメッセージを送信して確認する
Simulator上で、.apns
ファイルをドラッグ&ドロップして通知が来た場合にちゃんと動作するか確認する
{
"Simulator Target Bundle": "your-app-bundle-id-here",
"aps":{
"alert":"Test",
"sound":"default",
"badge":1
}
}
APNs証明書を使って、直接 APNsを呼び出してみて確認する
Google Developers Japan: iOS で Firebase Cloud Messaging をデバッグするの記事が参考になります。
openssl pkcs12 -in aps_development.p12 -out aps_development.pem -nodes -clcerts
curl --http2 --cert ./aps_development.pem \
-H "apns-topic: com.kumano-te.portfolio-ios" \
-d '{"aps":{"alert":"Hello from APNs!","sound":"default"}}' \
https://api.development.push.apple.com/3/device/your-APNs-device-token-here
Firebaseコンソールからテストメッセージを送信して届くかどうか確認する
こちらの記事を参考にして送信します。
PythonからFCMにメッセージを送信する(Topic編)
設定
- サービスアカウントを作成
- 鍵を作成してダウンロード
- 鍵のフルパスを
GOOGLE_APPLICATION_CREDENTIALS
に設定 firebase_admin
packageをインストール
# or you can instal via pip by `pip install firebase_admin`
% poetry add firebase_admin
Pythonでメッセージを送信
import firebase_admin
from firebase_admin import messaging
default_app = firebase_admin.initialize_app()
topic = 'articles'
title = "This is test..."
body = "New article has been published!"
ntf_data = {"key": "value"}
alert = messaging.ApsAlert(
title=title,
body=body,
)
aps = messaging.Aps(alert=alert, sound="default", badge=1)
payload = messaging.APNSPayload(aps)
message = messaging.Message(
notification=messaging.Notification(
title=title,
body=body,
),
data=ntf_data,
topic=topic,
apns=messaging.APNSConfig(payload=payload),
)
response = messaging.send(message)
print('Successfully sent message:', response)
以上になります。
関連する記事
[Jetpack Compose]Analytics / Crashlytics / FCMを導入
FirebaseをJetpack Composeアプリに導入して、プッシュ通知を受取り対応する画面を開くようにしました。またAnalyticsやCrashlyticsも同時に導入しました。
SwiftUIを使った開発のノウハウをまとめたiOSアプリをリリースしました
Kumanoteでよく使うSwiftUIコンポーネントの作り方をソースコードと共に公開しています。
SwiftUIでswiftのコードのシンタックスハイライトを表示する
SwiftのコードをSwiftUIベースのアプリでシンタックスハイライトされた状態で見れるViewを作ってみました
Tailwindcssで定義されている色からSwiftUI版の定義を自動生成する
Tailwindcssで定義されている便利な色たちをSwiftUIアプリでも利用したいので、jsonで定義されている色をSwiftUI Colorsの変数に変換するスクリプトを作りました