Flutterから利用できるFirebaseサービスをカウンターアプリで実践(Firebase Cloud Messaging編)
はじめに
Flutterから利用できるFirebaseの機能をカウンターアプリに実装し、内容をまとめたシリーズの第9回目です。
今回はクライアントアプリに対してプッシュ通知を送信できるFirebase Cloud Messagingについてです。
目次
シリーズの内容
回数 | 内容 | リンク |
---|---|---|
第0回 | 準備編 | ブログ |
第1回 | Analytics |
ブログ |
第2回 | Firebase Crashlytics |
ブログ |
第3回 | Firebase Performance Monitoring |
ブログ |
第4回 | Firebase Remote Config |
ブログ |
第5回 | Firebase Authentication |
ブログ |
第6回 | Cloud Firestore |
ブログ |
第7回 | Firebase Realtime Database |
ブログ |
第8回 | Cloud Storage for Firebase |
ブログ |
第9回 | Firebase Cloud Messaging |
イマココ |
第10回 | Firebase In-App Messaging |
ブログ |
第11回 | Firebase ML |
ブログ |
第12回 | Cloud Functions for Firebase |
ブログ |
第13回 | Firebase Hosting |
ブログ |
第14回 | Firebaseのその他のサービス | ブログ |
開発環境
項目 | 内容 |
---|---|
PC | Macbook Air(M1) |
Flutter | 3.0.1 |
Firebase | 11.0.1 |
FlutterFire | 0.2.2+2 |
デバッグデバイス | Android 12(APIレベル31) , Chrome |
準備
準備編が完了出来ているものとします。
導入方法
利用準備と条件はiOS
, Android
, Web
で異なっています。
今回のターゲットはAndroid
です。
iOS
での利用準備はセットアップの手順を確認してください。
Webで利用する場合、Firebase Consoleでの「ウェブプッシュ証明書」のキーペアを生成、firebase-messaging-sw.jsファイルの作成と登録等の設定が必要になります。
AndroidはAndroid4.4
以降のデバイスで実行できます。
プロジェクトにfirebase_messagingを導入するため、pubspec.yaml
に追記しインポートします。
dependencies: firebase_messaging: ^11.4.0
トークンのIDを取得します。
テストのときはトークンをprint
出力しておきます。
import 'package:firebase_messaging/firebase_messaging.dart'; // webの場合 // final fcmToken = await FirebaseMessaging.instance.getToken(vapidKey: 'BDdcxJZSBD...'); // モバイルの場合 final fcmToken = await FirebaseMessaging.instance.getToken(); print(fcmToken);
プラットフォームを問わず、バックグラウンドでもメッセージを受信する場合、以下のコードを追加します。
このとき、_firebaseMessagingBackgroundHandler
関数は無名関数であってはならず、トップレベルの関数として扱わなければ、エラーが発生します。
Future<void> main() async { /// 追加 FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); runApp(... } /// 追加 Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(); print("Handling a background message: ${message.messageId}"); }
テスト配信します。
Firebase ConsoleのMessaging
で新しいキャンペーンを選択、「デバイスでのテスト」の場合、FCM登録トークンの中に先ほどprint
出力したトークンをコピペします。
端末にプッシュ通知が来たら成功です。
コード全文
前回からの変更点です。
Firebase Cloud Messaging
を実装- その他、コードの変更
- 一部のキーなどはクラスを使って隠しています
main.dart
抜粋
/// Flutter関係のインポート import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'dart:async'; /// Firebase関係のインポート import 'package:firebase_core/firebase_core.dart'; import 'firebase_options.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; /// プラットフォームの確認 final isAndroid = defaultTargetPlatform == TargetPlatform.android ? true : false; final isIOS = defaultTargetPlatform == TargetPlatform.iOS ? true : false; /// FCMバックグランドメッセージの設定 Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { await Firebase.initializeApp(); print('Handling a background message: ${message.messageId}'); } /// メイン void main() async { /// クラッシュハンドラ runZonedGuarded<Future<void>>(() async { /// Firebaseの初期化 WidgetsFlutterBinding.ensureInitialized(); /// FCMのバックグランドメッセージを表示 FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); await Firebase.initializeApp( name: isAndroid || isIOS ? 'counterFirebase' : null, options: DefaultFirebaseOptions.currentPlatform, ); /// クラッシュハンドラ(Flutterフレームワーク内でスローされたすべてのエラー) FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError; /// runApp w/ Riverpod runApp(const ProviderScope(child: MyApp())); }, /// クラッシュハンドラ(Flutterフレームワーク内でキャッチされないエラー) (error, stack) => FirebaseCrashlytics.instance.recordError(error, stack, fatal: true)); } /// MaterialAppの設定 class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Counter Firebase', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(), debugShowCheckedModeBanner: false, ); } } /// ホーム画面 class MyHomePage extends ConsumerStatefulWidget { const MyHomePage({Key? key}) : super(key: key); @override MyHomePageState createState() => MyHomePageState(); } class MyHomePageState extends ConsumerState<MyHomePage> { @override void initState() { super.initState(); /// FCMのパーミッション設定 FirebaseMessagingService().setting(); /// FCMのトークン表示(テスト用) FirebaseMessagingService().fcmGetToken(); } @override Widget build(BuildContext context) { ... } } /// Firebase Cloud Messageの設定 class FirebaseMessagingService { FirebaseMessaging messaging = FirebaseMessaging.instance; /// webとiOS向け設定 void setting() async { 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}'); } void fcmGetToken() async { /// モバイル向け if (isAndroid || isIOS) { final fcmToken = await messaging.getToken(); print(fcmToken); } // web向け else { final fcmToken = await messaging.getToken( vapidKey: FirebaseOptionMessaging().webPushKeyPair); print('web : $fcmToken'); } } }
GitHubのページを貼ります。