はじめに
エキサイト株式会社の高野です。エキサイトホールディングス Advent Calendar 2023の3日目を担当させていただきます。
今回はFlutterにおけるRiverpodのStreamProviderを使ってPushNotificationを実装した話です。
動作環境
Flutter: 3.13.4
hooks_riverpod: 2.3.4
riverpod_annotation: 2.0.4
rxdart: 0.27.1
実装方法
まず始めに実際のコードを載せておきます。
@Riverpod(keepAlive: true) Stream<PushNotificationData?> pushNotificationStream( PushNotificationStreamRef ref, ) async* { final event = await ref.watch(pushNotificationOnMessageProvider.future); yield ref.watch(pushNotificationProvider).onOpenMessage(event.data); } @Riverpod(keepAlive: true) Stream<RemoteMessage> pushNotificationOnMessage( PushNotificationOnMessageRef ref, ) { return Rx.merge([ Stream.fromFuture(FirebaseMessaging.instance.getInitialMessage()) .whereNotNull(), FirebaseMessaging.onMessage, FirebaseMessaging.onMessageOpenedApp, ]); }
まず一つ目のポイントとしているのは、Pushの監視状態は途中で切れてほしくないのでkeepAliveをtrueにしています。 次に以下の部分です。
return Rx.merge([ Stream.fromFuture(FirebaseMessaging.instance.getInitialMessage()) .whereNotNull(), FirebaseMessaging.onMessage, FirebaseMessaging.onMessageOpenedApp, ]);
初回の通知確認、アプリを開いている時に通知を開いた場合、アプリを閉じている時に通知を開いた場合という3つを区別なく処理をします。
こちらの各Streamを同一StreamにするProviderを作成しました。
final event = await ref.watch(pushNotificationOnMessageProvider.future); yield ref.watch(pushNotificationProvider).onOpenMessage(event.data);
そして ref.watch
を使用して流れてくる値を監視し、整形してまたStreamとして流します。
ref.listen(pushNotificationStreamProvider, (_, asyncValue) { final data = asyncValue.valueOrNull; if (data == null) { return; } // ここに遷移処理等を書く }
最後にこのProviderをlistenしてあげ、Push通知を開いた際の処理を書きます。
意外と行数も増えることなく書くことができました。
最後に
エキサイトではエンジニアを随時募集しています。 興味がありましたらお気軽にご連絡いただければ幸いです。