🔔
🔔StreamNotifierでpush通知を受け取る
読んでほしい人
- riverod generatorの知識がある人
- riverpod2.0でFCM使ってみるのに、興味がある人
- FirebaseのFCMを使ったことある人
補足情報
Androidの実機で動作検証してます。iOSには今回対応しておりません🙅
もしやるならこのコードが必要ですね。Apple Developerアカウントも必要です。
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}');
記事の内容
Firebase FCMを使って、Androidの端末に通知のタイトル(title)と通知のテキスト(body)を送信してみようと思います。遅延があるみたいで、2回ぐらい実行したり少し待ったら通知が端末に来ました???
fcm tokenが必要なので、logを出すコードを書いておいてください。print
でもlogger
でも良いです。
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:hooks_example/fcm_example/fcm_stream_view.dart';
import 'package:hooks_example/firebase_options.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
// fcm tokenを取得
final fcmToken = await FirebaseMessaging.instance.getToken();
// fcm tokenを表示
debugPrint('🐈fcm token: $fcmToken');
runApp(const ProviderScope(child: MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const FcmStreamView(),
);
}
}
リアルタイムに取得しないと通知をViewに表示できないので、StreamNotifierを使います。通知をView側に表示するには、画面を更新してあげる必要があります。昔だとStateNotifierでやるみたいです。
実験用のコードなのでよくはないかも?
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
part 'fcm_stream_notifier.g.dart';
class FcmStreamNotifier extends _$FcmStreamNotifier {
// Stream<List<RemoteMessage>>のデータ型を返す
Stream<List<RemoteMessage>> build() {
// listという空のリストを作成
var list = <RemoteMessage>[];
// FirebaseMessaging.onMessage.mapでメッセージを受け取る
return FirebaseMessaging.onMessage.map((message) {
// listにFirebaseMessaging.onMessage.mapで受け取ったメッセージを追加
list.add(message);
// onDisposeでlistをクリア
ref.onDispose(() {
list.clear();
});
return list;
});
}
}
View側のコードは、通知が来るたびにリアルタイムに、内容を表示します。titleが通知のタイトル。bodyが通知のテキストの内容です。このコードも実験用なので、微妙ですね。
import 'package:flutter/material.dart';
import 'package:hooks_example/fcm_example/fcm_stream_notifier.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
class FcmStreamView extends HookConsumerWidget {
const FcmStreamView({super.key});
Widget build(BuildContext context, WidgetRef ref) {
final asyncValue = ref.watch(fcmStreamNotifierProvider);
return Scaffold(
appBar: AppBar(
title: const Text('FCM Stream Riverpod🐈'),
),
body: Center(
child: asyncValue.when(
data: (messages) {
return ListView.builder(
itemCount: messages.length,// mstの数だけリストを作成
itemBuilder: (context, index) {
final message = messages[index];
return ListTile(
title: Text('Message data: ${message.notification!.title}'),// タイトルを表示
subtitle: message.notification != null
? Text(
'Notification title: ${message.notification!.body}')// テキストの内容
: null,
);
},
);
},
loading: () => const CircularProgressIndicator(),
error: (error, stackTrace) => Text('Error: $error'),
),
),
);
}
}
ビルドしたら、logが出るので、tokenをコピーしてください。
こんな感じで、コンソールにtokenをコピペして設定して送信してみてください。
こんな感じですね。
最後に
今回は、riverpodで状態管理をして通知のテストをやってみました。スクラップに色々試行錯誤した記録もまとめているので、ご興味あれば見てください。
参考にした情報:
zennのスクラップ:
Discussion