Flutter + FCMで画像付きの通知を送受信する in iOS
FlutterとFirebase Cloud Messagingを使って下記のような通知を送受信したい場合の話。少々苦戦したのでメモ。
まずは基本的な通知を送受信するための設定。このやり方については巷にたくさん記事が出てるのでその通りに従っていけばまずつまづかないはず。下記の記事がメンテされてて良さそう。
次にこのドキュメントの (Advanced, Optional) Allowing Notification Images に書いてある設定を行う。
注意点としては、
- Notification Service Extensionはドキュメントのスクショ画像の通り、Swiftではなく Objective-C で作成する
-
Step 2 - Add target to the Podfile のpod installでRunner (true) and ImageNotification (false) do not both set use_frameworks!.のエラーが出る場合は
use_frameworks!
をtargetの外に出す。
use_frameworks! # <= ここへ移す
target 'Runner' do
# use_frameworks! これを↑へ
# some codes may be written in this lines.
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
target 'ImageNotification' do
pod 'Firebase/Messaging'
end
- Automatically manage signingを使っていない場合は、追加したNotification Service Extension用のProvisioning Profileを別途作成する。その際作成するbundle idは、もしメインのtargetが
com.example.app
でNotification Service Extensionの名前がImageNotificationならcom.example.app.ImageNotification
にする。そしてこのcom.example.app.ImageNotification
のidでIdentifiersを作り、provisioning profileを作成する。 -
com.example.app.ImageNotification
のIdentifiersを作成するときのCapabilitiesは何もオンにしなくて良い
とまぁこんな感じ。
今度は送信について。CloudFunctions+Node.jsで書く場合は例えばこんな感じで送信する。
const payload = {
// 個別の端末に送信したい場合はこんな風に指定する
token: 'this_is_a_device_token_to_send_to_a_specific_user_device',
notification: {
title: 'タイトル',
body: '本文',
},
android: {
notification: {
image: 'https://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg',
},
},
apns: {
payload: {
aps: {
"mutable-content": 1, // 画像を受け取れるようにするための設定
"content-available": 1,
badge: 1234,
},
},
fcm_options: {
// 表示したい画像のurl
image: 'https://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg',
},
},
data: {
hoge_custom_id: 'abcdefg',
click_action: "FLUTTER_NOTIFICATION_CLICK",
},
};
admin
.messaging()
.send(message) // sendToDevice()ではなくsend()を使わないと画像を送信できない
.then(() => {
return Promise.resolve(null);
});
注意点としては、コメントにも書いているがsendToDevice
ではなくsend
メソッドを使うこと。sendToDeviceはLegacyAPIを使ってるのでsendを使わないと画像を送信できないっぽい。
指定できるPayloadの仕様についてはこのドキュメント。
一般に送信の際の具体例については公式のこのドキュメントに色々と書いてある。
あとペイロードのaps
に何を設定できるのかについてはAppleの下記のドキュメントに書いてある。
その他、公式のドキュメントではないけどこの記事はFCMの受信時の挙動について詳しく解説してくれているのでよかった。
release buildを行うときにこんなエラーが出る場合がある。
Multiple commands produce '/Users/hoge/Library/Developer/Xcode/DerivedData/Runner-earpwkppmyngbcgtloibozoqeuwx/Build/Intermediates.noindex/ArchiveIntermediates/Runner/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/GoogleUtilities.framework':
1) Target 'GoogleUtilities-00567490' has create directory command with output '/Users/hoge/Library/Developer/Xcode/DerivedData/Runner-earpwkppmyngbcgtloibozoqeuwx/Build/Intermediates.noindex/ArchiveIntermediates/Runner/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/GoogleUtilities.framework'
2) Target 'GoogleUtilities-54e75ca4' has create directory command with output '/Users/hoge/Library/Developer/Xcode/DerivedData/Runner-earpwkppmyngbcgtloibozoqeuwx/Build/Intermediates.noindex/ArchiveIntermediates/Runner/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/GoogleUtilities.framework'
その場合はエラーメッセージにもある通り、GoogleUtilities
を各ターゲットに指定する。

このスクラップを見て自分の方で試していてうまくいきました!
良スクラップありがとうございます!
一つ詰まったところを共有しときます!
このスクラップのサンプルコードに使われている画像ですが
https://upload.wikimedia.org/wikipedia/commons/9/9e/Flag_of_Japan.svg
svgの画像となっています
公式ドキュメントを見ると
デバイスにダウンロードされ、通知に表示される画像の URL が含まれます。 JPEG、PNG、BMP は、プラットフォーム間で完全にサポートされています。アニメーション GIF とビデオは iOS でのみ機能します。 WebP と HEIF のサポート レベルは、プラットフォームとプラットフォームのバージョンによって異なります。 Android には 1MB の画像サイズ制限があります。 Firebase Storage でイメージをホストするための割り当て使用量と影響/コスト: https://firebase.google.com/pricing
https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?hl=ja#notification
このようにありsvgは正式サポートという訳ではなさそうです!
ですので、同じコードを使うと表示されない可能性が高いです
検証用にはjpgのURLを使うと正しく検証できそうです!
似てるjpg画像:
https://upload.wikimedia.org/wikipedia/commons/f/f4/Flag_of_Japan.jpg