この記事はFlutter 3.24を前提にしています。

FCMのアーキテクチャ概要(出典) https://firebase.google.com/docs/cloud-messaging/fcm-architecture
Firebase Cloud Messaging(FCM)は、無料でメッセージを安定して送信できるクロスプラットフォームのメッセージングサービスです。
FCMでメッセージを送受信するには、主に次の2つが必要です。
- Cloud Functions for Firebaseやアプリサーバーなど、メッセージの作成、宛先の指定、送信ができる信頼できる環境
- プラットフォームごとの配信サービスからメッセージを受け取るApple、Android、Web(JavaScript)のクライアントアプリ
通常、1つ目はバックエンド、2つ目はFlutterアプリです。今回は主に2つ目を扱い、FlutterでFCMトークンを取得してプッシュ通知を受け取る方法を見ていきます。
Apple Developerアカウントが必要です。持っていなければ
Apple Developer↗に登録するか、ここを飛ばしてAndroidの設定だけ行ってください。
- 任意の名前を入力し、APNsを選びます。
- Configureを押し、用途に合う項目を選んで設定を完了します。
- Continue、Registerの順に押すと、キーが作られます。
🖐️
ここで必ずキーをダウンロードし、安全な場所に保存してください。
完了すると、次のようにキーが発行されます。
- App IDsを選び、次の画面でAppを選択してContinueを押します。
- 説明とBundle IDを入力し、下までスクロールしてPush Notificationsを選びます。Continue、Registerの順に押して識別子の作成を完了します。
Bundle IDは
/ios/Runner.xcodeproj/project.pbxproj の PRODUCT_BUNDLE_IDENTIFIER の値です。例は com.example.promleeblog です。
1.3. XcodeでCapabilityを追加する 🔗
VS Codeで
/ios フォルダーを右クリックし、Open in Xcodeを押します。
Runner > Runner > Signing & Capabilities タブに移動し、
+ Capability を押して
Push Notifications を検索し、追加します。
さらに、Signing & Capabilities タブのBackground Modesで、次のようにチェックを入れます。
1.4. Firebaseコンソールを設定する 🔗

チームIDの確認場所
これでiOSの設定は完了です。
/ios/Podfile に次のように権限を追加します。すでに追加済みなら、PERMISSION_NOTIFICATIONS のコメントが解除されていることを確認します。
Podfileのコード
/ios/Podfilepost_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
target.build_configurations.each do |config|
# You can remove unused permissions here
# for more information: https://github.com/BaseflowIT/flutter-permission-handler/blob/master/permission_handler/ios/Classes/PermissionHandlerEnums.h
# e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
'$(inherited)',
## dart: PermissionGroup.calendar
# 'PERMISSION_EVENTS=1',
## dart: PermissionGroup.calendarFullAccess
# 'PERMISSION_EVENTS_FULL_ACCESS=1',
## dart: PermissionGroup.reminders
# 'PERMISSION_REMINDERS=1',
## dart: PermissionGroup.contacts
# 'PERMISSION_CONTACTS=1',
## dart: PermissionGroup.camera
# 'PERMISSION_CAMERA=1',
## dart: PermissionGroup.microphone
# 'PERMISSION_MICROPHONE=1',
## dart: PermissionGroup.speech
# 'PERMISSION_SPEECH_RECOGNIZER=1',
## dart: PermissionGroup.photos
# 'PERMISSION_PHOTOS=1',
## The 'PERMISSION_LOCATION' macro enables the `locationWhenInUse` and `locationAlways` permission. If
## the application only requires `locationWhenInUse`, only specify the `PERMISSION_LOCATION_WHENINUSE`
## macro.
##
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
# 'PERMISSION_LOCATION=1',
# 'PERMISSION_LOCATION_WHENINUSE=0',
## dart: PermissionGroup.notification
'PERMISSION_NOTIFICATIONS=1',
## dart: PermissionGroup.mediaLibrary
# 'PERMISSION_MEDIA_LIBRARY=1',
## dart: PermissionGroup.sensors
# 'PERMISSION_SENSORS=1',
## dart: PermissionGroup.bluetooth
# 'PERMISSION_BLUETOOTH=1',
## dart: PermissionGroup.appTrackingTransparency
# 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',
## dart: PermissionGroup.criticalAlerts
# 'PERMISSION_CRITICAL_ALERTS=1',
## dart: PermissionGroup.criticalAlerts
# 'PERMISSION_ASSISTANT=1',
]
end
end
end
Androidでは、権限を設定します。Android 13(APIレベル33)以降が対象です。
/android/app/src/main/AndroidManifest.xml<manifest ...>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<application ...>
...
</application>
</manifest>
3. Flutterでプッシュ通知を受信するコードを書く 🔗
3.1. firebase_messagingパッケージをインストールする 🔗
flutter pub add firebase_messaging
通知の許可を求める箇所に、次のコードを追加します。
import 'package:firebase_messaging/firebase_messaging.dart';
// 적절한 위치에 선언
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
print('User granted permission: ${settings.authorizationStatus}');
3.3. プッシュ通知の受信コードを書く(バックグラウンド) 🔗
エントリーポイントのmain.dartに、次のコードを追加します。
バックグラウンドのメッセージハンドラーについて、いくつか注意点があります。
- 匿名関数は使えません。
- トップレベルの関数である必要があります。初期化が必要なクラスメソッドなどは使えません。
- Flutter 3.3.0以降では、関数宣言の直前に @pragma('vm:entry-point') を付ける必要があります。付けないと、リリースモードのツリーシェイキングで削除される場合があります。
/lib/main.dartimport 'package:firebase_messaging/firebase_messaging.dart';
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
}
void main() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
3.4. プッシュ通知の受信コードを書く(フォアグラウンド) 🔗
エントリーポイントのファイルに、次のリスナーを追加します。
/lib/main.dartimport 'package:firebase_messaging/firebase_messaging.dart';
void main(){
// ...
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message whilst in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
});
runApp(MyApp());
}
FCMトークンは、FlutterアプリがFCMサーバーと通信するための固有の識別子です。Flutterアプリでトークンを取得すると、プッシュ通知を受信できます。
import 'package:firebase_messaging/firebase_messaging.dart';
// 적절한 위치에 선언
final req = await FirebaseMessaging.instance.requestPermission(
alert: true,
badge: true,
sound: true,
);
final fcmToken = await FirebaseMessaging.instance.getToken();
if (req.authorizationStatus == AuthorizationStatus.authorized && fcmToken != null) {
print('FCM Token: $fcmToken');
} else {
print('FCM Token: null');
}
通知を作成する画面が出たら、タイトルと本文を入力します。「テストメッセージを送信」を押すと、上で取得したFCMトークン宛に通知を送れます。
apns token has not been set yet. please ensure the apns token is available by calling getapnstoken()
基本設定が正しくてもこのエラーが出る場合、FlutterがAPNsトークンを自動取得できていない可能性があります。その場合は手動でAPNsトークンを取得します。
/lib/main.dartimport 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
FirebaseMessaging messaging = FirebaseMessaging.instance;
await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
messaging.getAPNSToken(); // 이 코드 추가
await messaging.getToken();
runApp(MyApp());
}
iOSの実機にアプリをインストールして実行すると、上のエラーが出ることがあります。iOSでFCMトークンを取得するには、APNsトークンが必要なためです。アプリを起動し、APNsトークンを取得してからFCMトークンを取得するよう、上記の手順でコードを修正します。
Firebase Cloud Messagingを使えば、プッシュ通知を簡単に送れます。一方で、通知をタップしたときに特定の画面へ移動したり、特定の処理を実行したりするには、追加の実装が必要です。次回の記事で扱います。
- HTTP v1 APIでプッシュ通知を送る
- プッシュ通知をタップしたら特定のページへ移動する
- プッシュ通知をタップしたら特定の処理を実行する