FlutterのAndroidアプリで、プッシュ通知を受けてバナー表示しようとしたのですが、色々困ったので情報をまとめておきます。
FCMの準備
Firebase Cloud Messagingでプッシュ通知を実現します。
FCMの設定は色々な人が記事上げていると思うのでそちらを参考にしてください。
プッシュ通知トークンを取得する
// これでトークンが取得できる
var token = await FirebaseMessaging.instance.getToken();
Flutter で Firebase Cloud Messaging クライアント アプリを設定するには下記記載がありましたが、これで取得できるタイミングはよくわかりませんでした。
FirebaseMessaging.instance.onTokenRefresh
.listen((fcmToken) {
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new
// token is generated.
})
.onError((err) {
// Error getting token.
});
プッシュ通知権限を要求する
Android13からAndroidでもプッシュ通知権限の要求が必要になりました。
Flutter アプリでメッセージを受信するに記載しておいて欲しいですね。
プッシュ通知権限要求のパッケージnotification_permissionsがあるのですが、Android13対応がされていません。(ここでちょっと詰まりました)
issueを見ればわかりますが、誰かが対応ブランチを作ってくれているのでそれを利用します。(なんでマージされてないの??)
pubspec.yamlに下記を追加します
notification_permissions:
git:
url: https://github.com/bshvets8/flutter_notification_permissions.git
ref: feature/android-13-support
AndroidManifest.xmlにuses-permissionを追加します。
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
参考:通知に関する実行時の権限
後はパッケージサンプル説明の通り、権限要求のコードを呼び出せば大丈夫です。
PermissionStatus permissionStatus =
await NotificationPermissions.requestNotificationPermissions();
フォアグラウンドでプッシュ通知を受けてバナーを表示する
LINEとかでよく見るバナー通知を表示するためには、通知チャネルを作成して、重要度を高にしないとダメなようです。
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'channel_id',
'high importance channel',
importance: Importance.max,
);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
次にフォアグラウンドでバナーを表示するためには、flutter_local_notifications を使って、ローカルプッシュ通知の呼び出しが必要とのことです。
参考:Flutter×Firebase(CloudMessaging)で、フォアグラウンド/バックグラウンドで通知をしてみる - Qiita
// 通知アイコンの設定が必要なため事前に設定しておく
var initializationSettingsAndroid =
const AndroidInitializationSettings('@mipmap/ic_launcher');
var initializationSettings =
InitializationSettings(android: initializationSettingsAndroid);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
// flutter_local_notificationsでバナー表示
FirebaseMessaging.onMessage.listen((message){
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
if (notification != null && android != null) {
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
),
),
);
}
});
参考:Notifications | FlutterFire
バックグランドでプッシュ通知を受けてバナー表示する
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
print("Handling a background message: ${message.messageId}");
}
void main() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
イベントハンドラはログ出力するコードしかありませんが、これでバナー表示されます。
ただし、重要度高の通知チャネルで処理する必要があるため、
プッシュ通知送信時に通知チャネルを指定するか、AndroidManifest.xmlにデフォルト通知チャネルの指定を追加するかのどちらが必要です。
<application
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="channel_id" />
参考:Cloud Messaging | FlutterFire
以上!