65
59

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Flutter #2Advent Calendar 2020

Day 16

【Flutter】FCMで初めてのプッシュ通知 2020年12月版

Last updated at Posted at 2020-12-15

Flutter #2 Advent Calendar 2020 の 16日目 の記事となります。
Flutterが気になる方は Flutter #1Flutter #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を選択します。
fcma01.png
次にどのタイプのプロジェクトを作成するか聞かれるのでFlutter Applicationを選択します。
Project nameflutter_fcm_first_sampleとしました。
Package namecom.yana1316.flutter_fcm_first_sampleとしました。この名前はFirebaseやXcodeの設定でも使いますので覚えておいて下さい。

Firebaseでプロジェクトの作成

Firebaseのアカウントの作成
Googleアカウントが無い方は作成してください。
プロジェクトの追加
プロジェクト名をflutter-fcm-first-sampleとしました。Google Analyticsの追加は、どちらでも大丈夫です。

Android用設定

Firebase設定

アプリの登録
プロジェクト追加後、画面上からAndroid用アプリを登録します。
fcm01.png
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/に置きます。
flutter_fcm_first_sample_–google-services_json__flutter_fcm_first_sample_android.png
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に移動します。
fcm06.png
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が開きます。
fcm07a.png

アカウント設定
Xcode画面左上のほうにあるShow the project navigatorをクリックしRunnnerをクリックします。
Runner_xcodeproj.png
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 NotificationsBackground Modesを追加してください。
fcm08.png

Firebaseの設定

iOSアプリを追加
Firebaseの画面から+アプリの追加を選択しiOSを追加ます。
アプリの登録
iOSバンドルIDはXcodeのSigning画面内にあるBundle Identifierとなります。
設定ファイルのダウンロード
GoogleService-Info.plistをダウンロードし、Xcodeの下記の場所に移動します。
fcm08.png

Firebase SDK の追加
何もせず次へを押してスキップします。
初期化コードの追加
何もせず次へを押してスキップします。
次のステップ
何もせずコンソールに進むを押します。

APNs認証キー の登録
Firebaseメニューの歯車からプロジェクトを設定を選択します。
fcm09.png
Cloud MessagingiOSアプリからAPNs認証キーアップロードを選択します。
fcm10.png
Apple Developer ProgramKeysで作成した.p8ファイルをアップロードし、キーIDは下記のKeysの詳細画面から確認します。
fcm11.png
チームIDApple Developer Program内のIdentifiersにある自動生成された証明をの詳細を開くと下記のようにTeam IDが確認できます。
fcm13.png

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で確認できます。onLaunchonResumeonBackgroundMessageなどは設定条件もありますので、詳細はPlugin公式をご確認ください。

_firebaseMessaging.configure(
  onMessage: (Map<String, dynamic> message) async {
    setState(() {
      _message = "onMessage: $message";
    });
    print("onMessage: $message");
  },
  /// 省略
);

動作確認

Tokenの取得

Android Studioでシミュレーターを実行すると、画面上にtokenが表示されます。
fcm15.png

またAndroid StudioのConsoleにtokenがprintされますのでコピーしておきます。
fcm14.png

Firebase Cloud Messagingからの送信テスト

FirebaseのCloud MessageingにあるSend your first messageを開きます。
fcm16.png

タイトルやテキストを適当に埋めてテストメッセージを送信ボタンを押します。
fcm17.png

表示されたダイアログにコピーしておいた送信先のtokenを貼り付けしテストボタンを押します。
fcm18.png

シミュレーターにメッセージが表示されれば成功です!
fcm19.png

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で行う場合、結構な壁になるのかなぁとも思いました。少しでも参考になればと思います。
不明点や間違いなどありましたら、ご質問、ご指摘下さい!

65
59
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
65
59

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?