Flutter #2 Advent Calendar 2020 の 16日目 の記事となります。
Flutterが気になる方は Flutter #1 やFlutter #3もありますので、ぜひご覧になってください。
概要
私が初めてPush通知を実装したとき苦労した記憶がありました。そこで初めてのモバイルアプリ開発をFlutterで行う人に対しての「この記事を参考にすれば最低限のPush通知が確認できる」という内容にしました。
また、基本的には下記pluginページの流れと同じものになります。
https://pub.dev/packages/firebase_messaging
※ このFCM用の設定を本番、開発で切り替えたい場合はこちらの記事を参考にしてください。
前提
- Flutterの環境構築は完了している
- Firebaseを使ってPush通知を実装したい
環境
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 1.22.4, on Mac OS X 10.15.7 19H2 darwin-x64, locale en-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 12.1)
[✓] Android Studio (version 4.1)
[✓] Connected device (1 available)
サンプルコード
Flutterプロジェクトの作成
Create New Flutter Project
を選択します。
次にどのタイプのプロジェクトを作成するか聞かれるのでFlutter Application
を選択します。
Project name
はflutter_fcm_first_sample
としました。
Package name
はcom.yana1316.flutter_fcm_first_sample
としました。この名前はFirebaseやXcodeの設定でも使いますので覚えておいて下さい。
Firebaseでプロジェクトの作成
Firebaseのアカウントの作成
Googleアカウントが無い方は作成してください。
プロジェクトの追加
プロジェクト名をflutter-fcm-first-sample
としました。Google Analyticsの追加は、どちらでも大丈夫です。
Android用設定
Firebase設定
アプリの登録
プロジェクト追加後、画面上からAndroid用アプリを登録します。
Android パッケージ名
Android StudioでProject作成時に設定したPackage name
を入力します。
パッケージ名を忘れてしまった場合
Android Studioで確認できます。 ![fcm02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315258/2a301a80-9c7a-af09-d854-e1e802a893a5.png)設定ファイルのダウンロード
google-services.json
をダウンロードし、[project]/android/app/
に置きます。
google-services.json
は機密情報ではありませんが、公開されたgit等で管理しないようにしましょう。(いろいろと狙われる原因になりがちですので)
Firebase SDK の追加(スキップ)
何もせず次へ
を押してスキップします。
次のステップ
何もせずコンソールに進む
を押します。
Android Studioでの設定
[project]/android/build.gradle
に追記します。
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.3.4' // 追記
}
`com.google.gms:google-services` の最新バージョン
以下のページの`Google Play services plugin`で最新バージョンを確認することができます。 https://firebase.google.com/support/release-notes/android#latest_sdk_versions[project]/android/app/build.gradle
に追記します。
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
apply plugin: 'com.google.gms.google-services' // 追記
[project]/android/app/src/main/AndroidManifest.xml
の40行目付近に追記します。
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
※ 今回、バックグラウンド処理用の設定は省略しています。詳細は以下から確認してください。
https://pub.dev/packages/firebase_messaging#optionally-handle-background-messages
##iOS用設定
Apple Developer Programでの設定
アカウントの作成
Apple IDでも開発できるのですが、たぶんPush通知を行うには有料のApple Deeloper Programに登録する必要がありそうです。下記ページのAppの高度な機能とサービス
にPush通知で利用するPush Notifications
機能が含まれている気がします。
https://developer.apple.com/jp/support/compare-memberships/
Apple Developer Programのアカウントを作成したらログインして、以下のCertificates, Identifiers & Profiles
に移動します。
Keys の作成
Certificates, Identifiers & Profiles
に移動後、左メニューのKeys
をクリックします。
+
ボタンを押して新しいKeyを追加します。Keyの名前はご自由にですがproduct key
とかmain key
とかにするのでしょうか。
※ このKeyは、1つのアカウントで2つまでしか作れません。つまり複数のアプリを作ったとしても共通のKeyとなります。
※ 今回はFirebase FCMを使ってのPush通知となりますので、APNs用証明書(.cer)(.p12)
は使わず、FirebaseがおすすめするAPNs認証キー(.p8)
を使います。
Xcodeの設定
Android StudioのProject Windowから下記の[project]/ios
を右クリックしFlutter
内のOpen iOS module in Xcode
をクリックします。すると該当ProjectのXcodeが開きます。
アカウント設定
Xcode画面左上のほうにあるShow the project navigator
をクリックしRunnner
をクリックします。
Automatically manage signing
にチェックを付け、Teamで自分のApple Deeloper Program アカウント
を選択(追加)します。
`Automatically manage signing`での設定について
※ Signingにはいくつかの方法がありますが、Autoでの説明をしています。この他に`Apple Developer Program`に自分で証明書を用意する方法、`fastlane`などを使ってチーム内で証明書を簡単に共有しつつ設定する方法などがあります。 ※ `Automatically manage signing`にチェックをつけるとXcodeが`Apple Developer Program`にログインし、証明書をアップロードしてくれます。`Identifiers`のページを見ると `XC`から始まる証明書が登録されていますが、これは`Xcode`が登録したもので、`XC`は`Xcode`略称だと思われます。Capabilityの追加
以下の+Capability
からPush Notifications
とBackground Modes
を追加してください。
Firebaseの設定
iOSアプリを追加
Firebaseの画面から+アプリの追加
を選択しiOSを追加ます。
アプリの登録
iOSバンドルID
はXcodeのSigning画面内にあるBundle Identifier
となります。
設定ファイルのダウンロード
GoogleService-Info.plist
をダウンロードし、Xcodeの下記の場所に移動します。
Firebase SDK の追加
何もせず次へ
を押してスキップします。
初期化コードの追加
何もせず次へ
を押してスキップします。
次のステップ
何もせずコンソールに進む
を押します。
APNs認証キー の登録
Firebaseメニューの歯車からプロジェクトを設定
を選択します。
Cloud Messaging
のiOSアプリ
からAPNs認証キー
のアップロード
を選択します。
Apple Developer Program
のKeys
で作成した.p8ファイルをアップロードし、キーID
は下記のKeys
の詳細画面から確認します。
チームID
はApple Developer Program
内のIdentifiers
にある自動生成された証明をの詳細を開くと下記のようにTeam ID
が確認できます。
Flutterの設定
基本的には、下記のサンプルコードを参考にしてもらえれば大丈夫なはずです。
https://github.com/yana1316/flutter_fcm_first_sample
.yaml
pubspec.yaml
に追記します。
dependencies:
flutter:
sdk: flutter
firebase_messaging: ^7.0.3 # 追加
main.dart
Firebase用のSDKを用意
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
iOS用 Push通知の許可
「xxxはあなたにプッシュ通知を送信します。よろしいですか?」を表示させるやつです。
/// iOS用 PUSH通知の許可確認
_firebaseMessaging.requestNotificationPermissions(
const IosNotificationSettings(sound: true, badge: true, alert: true));
FCM用Tokenの取得
FCMサーバーにデバイスID?を送信して、デバイス固有のTokenを取得します。このTokenは、FCMからメッセージを送信するときの宛先となります。
/// iOS用 PUSH通知の許可確認
/// FCM token の取得
_firebaseMessaging.getToken().then((String token) {
assert(token != null);
setState(() {
_token = token;
});
print("token: $_token");
});
メッセージ受診時の処理
FCMからメッセージを受信したさいの処理を記載します。必要最低限の動作はonMessage
で確認できます。onLaunch
やonResume
、onBackgroundMessage
などは設定条件もありますので、詳細はPlugin公式をご確認ください。
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
setState(() {
_message = "onMessage: $message";
});
print("onMessage: $message");
},
/// 省略
);
動作確認
Tokenの取得
Android Studioでシミュレーターを実行すると、画面上にtokenが表示されます。
またAndroid StudioのConsoleにtokenがprintされますのでコピーしておきます。
Firebase Cloud Messagingからの送信テスト
FirebaseのCloud MessageingにあるSend your first message
を開きます。
タイトルやテキストを適当に埋めてテストメッセージを送信
ボタンを押します。
表示されたダイアログにコピーしておいた送信先のtokenを貼り付けしテスト
ボタンを押します。
Consoleからの送信テスト
curlが使えるconsoleからも送信テストができます。以下はmacでの例です。
server key
は Fireaseの設定
内、Cloud Messaging
タブにあるサーバーキー
となります。
project id
は Fireaseの設定
内、全般
タブにあるプロジェクトID
となります。
以下をconsoleにコピペし、key=${server key}
などをkey=hogehoge
と置き換えて実行すれば送信されるかと思います。
curl -X POST \
--header "Authorization: key=${server key}" \
--header "project_id: key=${project id}" \
--header Content-Type:"application/json" \
https://fcm.googleapis.com/fcm/send \
-d @- << EOF
{
"to": "${fcm token}",
"notification": {
"body": "curl test"
},
}
EOF
正しく送信されると以下のようなResponseが戻り、シミュレーターにもメッセージが表示されます。
{"multicast_id":7325921480228621614,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1607493418784266%a3c83467a3c83467"}]}
私がハマったポイント
- Xcodeの証明書に不慣れで
Automatically manage signing
について理解できていなかった - APNs証明書で Keys(.p8) でよかったのに、がんばって .p12 を作ってしまった
- シミュレーターではPush通知の受け取りに制約があることを知らなかった
- 開発用証明書(Development)と本番証明書(Distribution)、AdHoc証明書、の違いがわかっていなかった
- iOSではアプリがバックグラウンド時にメッセージを受信しバックグラウンド処理を行うことが難しいことについてについて、しばらくしてから気づいた(今は簡単に出来るのかも?)
まとめ
最低限のPush通知をFCMを利用して送信してみる内容でした。AndroidやiOS開発からFlutterに移動したかたは慣れていると思いますが、初めてのモバイルアプリ開発をFlutterで行う場合、結構な壁になるのかなぁとも思いました。少しでも参考になればと思います。
不明点や間違いなどありましたら、ご質問、ご指摘下さい!