Firebase Cloud MessagingでFlutter Web Appにプッシュ通知を送信してみた
こんにちは、CX事業本部 IoT事業部の若槻です。
Flutterアプリへのプッシュ通知の実装について検討していたところ、Firebase Cloud Messagingが便利だと聞きました。
今回は、Firebase Cloud Messaging(FCM)でFlutter Web Appにプッシュ通知を送信してみました。
やってみた
下記ドキュメントを参考に、FCMのコンソールからテスト通知をFlutter Web Appへ送信できるようにしてみます。
Firebase CLIのインストール、認証
Firebase CLIをグローバルインストールします。
$ npm install -g firebase-tools
パスが通っていることを確認します。
$ firebase --version 10.6.0
Firebase CLIの認証を行います。次のコマンドを実行するとブラウザ画面が開き、Firebase(Google)の認証およびアクセス権の委譲を求められるのでサインインおよび許可します。
$ firebase login
CLI画面に戻り、次のように表示されれば認証成功です。
✔ Success! Logged in as hoge@example.com
参考
flutter project作成
Flutterプロジェクトを新規作成します。
$ flutter create flutter_sample_app $ cd flutter_sample_app
https://pub.dev/packages/firebase_coreプラグインをインストールします。
$ flutter pub add firebase_core
この時作成されるlib/generated_plugin_registrant.dart
でエラーが発生しているかと思いますが、後節で対応するので一旦無視してください。
Target of URI doesn't exist: 'package:firebase_core_web/firebase_core_web.dart'. Try creating the file referenced by the URI, or Try using a URI for a file that does exist.
FlutterFire CLIのインストール
FlutterFire CLIをグローバルインストールします。
$ dart pub global activate flutterfire_cli
FlutterFire CLIにパスを通します。
$ export PATH="$PATH":"$HOME/.pub-cache/bin"
FlutterFire CLIにパスが通っていることを確認します。
$ flutterfire --version 0.2.0
次のコマンドを実行してFirebaseにFlutter Web App用のプロジェクトを作成します。
$ flutterfire configure ✔ Enter a project id for your new Firebase project (e.g. my-cool-project) · flutter-wakatsuki-app ✔ Which platforms should your configuration support (use arrow keys & space to select)? · web
この時作成されるlib/firebase_options.dart
でも先程と同様のエラーが発生しているかと思います。
次のコマンドを実行して不足しているパッケージをインストールします。するとエラーは解消するはずです。
$ flutter packages get
アプリへのCloud Messagingの導入
Firebase Cloud Messagingのコンソールで、先程作成したプロジェクトのWeb Push certificateを作成し、Key pairを控えます。
FCMのパッケージをインストールします。
$ flutter pub add firebase_messaging
main.dart
の冒頭を次のように修正します。messaging.getToken()
のvapidKey
には先程取得したKey pairを指定します。これによりパーミッションの設定、トークンの取得およびフォワグラウンドでのメッセージのリッスンをできるようにします。
import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; import 'firebase_options.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; void main() async { //イニシャライズ WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); //パーミションの設定 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}'); //トークン取得 String token = (await messaging.getToken( vapidKey: "BGpdLRs......", )) .toString(); print(token); //メッセージのリッスン FirebaseMessaging.onMessage.listen((RemoteMessage message) { print('Got a message whilst in the foreground!'); if (message.notification != null) { print('onForegroundMessage Title: ${message.notification?.title}'); print('onForegroundMessage Body: ${message.notification?.body}'); } }); runApp(const MyApp()); }
こちらを参考にweb/firebase-messaging-sw.js
を作成します。これによりFirebase Cloud Messagingのテストメッセージをバックグラウンドでもリッスンできるようにします。
importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"); importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js"); firebase.initializeApp({ apiKey: "AIzaSyAgUhHU8wSJgO5MVNy95tMT07NEjzMOfz0", authDomain: "react-native-firebase-testing.firebaseapp.com", databaseURL: "https://react-native-firebase-testing.firebaseio.com", projectId: "react-native-firebase-testing", storageBucket: "react-native-firebase-testing.appspot.com", messagingSenderId: "448618578101", appId: "1:448618578101:web:ecaffe2bc4511738", }); // Necessary to receive background messages: const messaging = firebase.messaging(); // Optional: messaging.onBackgroundMessage((m) => { console.log("onBackgroundMessage", m); });
またweb/index.html
の<body>
の末尾に次のコードを追記します。これにより前述のjsファイルをサービスワーカーとして起動中のアプリに登録します。
<script> if ("serviceWorker" in navigator) { window.addEventListener("load", function () { navigator.serviceWorker.register("/firebase-messaging-sw.js"); }); } </script> </body>
動作確認
Flutter Web AppをChromeで起動します。
$ flutter run -d chrome
するとChromeブラウザでアプリが起動し、通知の許可を求められるので許可します。
またコンソールに表示されたトークンを控えます。
Firebase Cloud Messagingのコンソールで、[Cloud Messaging]で[Send your first message]をクリック。
[Notification title]および[Notification Text]を指定して、[Send test message]をクリック。
先程控えたトークンを指定して、[Test]をクリック。
するとFlutter Web Appにプッシュ通知が届きました!Chromeがフォアグラウンドである場合のメッセージとなっています。
またChromeをバックグラウンドとした状態で同じトークンを使用して再度テストメッセージを送信すると、次はバックグラウンドである場合のメッセージも届きました!
おわりに
Firebase Cloud Messaging(FCM)でFlutter Web Appにプッシュ通知を送信してみました。
Firebaseを扱うのはほぼ初めてでかなり試行錯誤をしましたが、なんとか動かせはしました。次回以降ではiOSなどのネイティブアプリで試してみたいです。
参考
- firebase - The Target URI doesn't Exist:'package:firebase_database/firebase_database.dart'; - Stack Overflow
- Diagnostic messages | Dart
- Firebase編7:Cloud Messaging|Flutter実践入門 ~環境構築からAndroid/iOS/Webに広告を付けて同時にリリース!!~
以上