From 13f923ab6066dd8bc47037abcb350a045710cfe0 Mon Sep 17 00:00:00 2001 From: kanat <> Date: Tue, 9 May 2023 15:09:16 -0700 Subject: [PATCH] implement PN support on iOS & Android --- .../android/app/src/main/AndroidManifest.xml | 6 + .../drawable-anydpi-v24/ic_notification.xml | 16 ++ .../ic_notification_in_app.xml | 15 ++ .../res/drawable-hdpi/ic_notification.png | Bin 0 -> 339 bytes .../drawable-hdpi/ic_notification_in_app.png | Bin 0 -> 345 bytes .../res/drawable-mdpi/ic_notification.png | Bin 0 -> 243 bytes .../drawable-mdpi/ic_notification_in_app.png | Bin 0 -> 213 bytes .../res/drawable-xhdpi/ic_notification.png | Bin 0 -> 434 bytes .../drawable-xhdpi/ic_notification_in_app.png | Bin 0 -> 444 bytes .../res/drawable-xxhdpi/ic_notification.png | Bin 0 -> 676 bytes .../ic_notification_in_app.png | Bin 0 -> 596 bytes packages/stream_chat_v1/lib/app.dart | 151 +++++++++++++++++- packages/stream_chat_v1/lib/main.dart | 28 +--- .../lib/pages/channel_list_page.dart | 10 +- .../lib/pages/channel_page.dart | 4 + .../lib/utils/notifications_service.dart | 4 +- 16 files changed, 208 insertions(+), 26 deletions(-) create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification_in_app.xml create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification.png create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification_in_app.png create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-mdpi/ic_notification.png create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-mdpi/ic_notification_in_app.png create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-xhdpi/ic_notification.png create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-xhdpi/ic_notification_in_app.png create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification.png create mode 100644 packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification_in_app.png diff --git a/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml b/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml index fa7cbe4..6f96e79 100644 --- a/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml +++ b/packages/stream_chat_v1/android/app/src/main/AndroidManifest.xml @@ -44,5 +44,11 @@ + + + \ No newline at end of file diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml b/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml new file mode 100644 index 0000000..b953a9c --- /dev/null +++ b/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification_in_app.xml b/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification_in_app.xml new file mode 100644 index 0000000..3c858bb --- /dev/null +++ b/packages/stream_chat_v1/android/app/src/main/res/drawable-anydpi-v24/ic_notification_in_app.xml @@ -0,0 +1,15 @@ + + + + + diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification.png b/packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification.png new file mode 100644 index 0000000000000000000000000000000000000000..89924d6f9005be86c0db6800b26d3ace49ea17ec GIT binary patch literal 339 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$UKzz$oSE;uum9_jZzRAakHVi!!68 z1q0{A4MGJCtVdUPo zQ?w3pzDroCwb#th)PmP`{T0ud59$u7E!(nxp>a-<*VG3r=gNb>FC6yT+061?*v#-M#FkzZ&YlAMg>U(ON$h%D z=QN$aN~-FQ``zO2;ZyjdUfdLs+4AB4vpKR`KHLxeVVUvp`|5@JZFbC^EB%CfgHsBp UB&(DqFt8XrUHx3vIVCg!0O4?tqW}N^ literal 0 HcmV?d00001 diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification_in_app.png b/packages/stream_chat_v1/android/app/src/main/res/drawable-hdpi/ic_notification_in_app.png new file mode 100644 index 0000000000000000000000000000000000000000..738f9dd5aa1e8b96c3b5910c8e9a04d5baa3bdef GIT binary patch literal 345 zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$UKzz^LHq;uum9_x9?=P9{fzmPF?r z0eURX1}(e~jV=hBIUu6PYz^d2F65TY_*Z1X_vUK*--LvhYnMGsOf;W;b(KSQuKE1p zk2g1d*JQn2^l#r4nO{%C7AEWu?1*k{`s=2cC(89rx^+jW#*KWDM_44LzL7^E{eI*6O9&J$Bms_wk%dZ{|F!dgqsEC-lag zt8jI|hWi>v);b-mTP(1hi}iP}(;Y1lToNTI`!i3+di>v||84fSKTh^<|Lv~0`ZMi) zz-MmXGdf)2vwqYSzH}14zxU{4C*kM$m;Ze}xHe4w1)E^{`7EQ`lYwEyz~JfX=d#Wz Gp$PzZ*PQnN literal 0 HcmV?d00001 diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-mdpi/ic_notification.png b/packages/stream_chat_v1/android/app/src/main/res/drawable-mdpi/ic_notification.png new file mode 100644 index 0000000000000000000000000000000000000000..bc99f1b28038fca3d188008f898c6b4df49edfb7 GIT binary patch literal 243 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjyF6VSLn`9lPB|!e$bg3>m`imD zb4ZtWA!mtzRRiCG$y*%Q+fzPmIRCAOt(~36x>)}A5?{M{%jPp5SYx?w=FIP+84tS( z_4b%IUZ4Kn^{;xB#vLh#ihA#Y>n`bQWlw*pS3@~VjGX|2|}2b+FrzDRZK^fowD&Mmjcx-qK2>90yf(Sy63 rQ<@HZKb+EZpnUfRPNw<)e_Ht8%dvm7=bcIx&=(Azu6{1-oD!M|t-J1gby?N^hHc&ZA)YQiI!^Eag#Ln|XiL z^&1P_$<#bk*8elIf}iE{v_m=HXUuQ??qHCQB6#?=U%JYU%Rw{VvNT!iw%&YaXwUt= zG2tFiK<@MA4{{vOPy};tlvybsoC`EfT>xx66AGu*dhM*wjNAX0uX|Q~K--+}sttd| z`u#s||6d|hzcP4+|MFk#B5A>^?%OXgm>%}`SHmHntO|#R-(QyUYy5eq7$YC> zh*g63Oui+|`JB@d)GsiqIs2L@s_2>+L>$f+=jw*kHl@l2Jd(@&y+D8o2%G*)9=6z<0S^SIVH;5MAEDo zAD^3WD5u}zNBO%yIqUoXF1EaUUN`mjx_hR_!OE1k8P8p4DP52@{n^JD@ma-JX9D#? z1Ye7PV2^pQ*>3i;oAG^pUrK9=tA1Rqd4D~2Z+0JX)?#(5#vRE|bHsQ2-CsQKJ=6O; z7AHT)Jb3W^&)fMckC>ZseSTR{(|9Py%dW2RP)yXn&rGc|uM{*M`ut@Ux5zx(*2}D1 l_VrSwf4J>m?^;*gq2Jk8l#@Qq$R8Lh44$rjF6*2UngBl0&)xt4 literal 0 HcmV?d00001 diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification.png b/packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification.png new file mode 100644 index 0000000000000000000000000000000000000000..f65b65435a9ab2b51bcc6e2d2dc201139695d2dd GIT binary patch literal 676 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2V9NG%aSW-5dwc6*uCyahOXBng ze0%4nczL)Nsh6>PvY+97!gB0=i`}V1T94kczv(VDRudOmz;0`!b9xg9&F|_s{?;b< z`R%#$mcO+rTEF^6*YUEtBY!{hHUF;d;6r9Zuw0ZtV1}d&g}ewg+fXD&Zy@2cKp0)!`$xG@zZGf z22;gn>7RLIv=pD6jyZI#Wybuo#sw={X6OU0LD7`!a%VeGFO>4#bL?mJ3ElJAZ`9vK zKNH%fcH~dayhdl$BQ-OqrORK3J(r!(iDNm_(BoteI~Wi6+n{p|Dy z0i1^M7@8_>o_l%hxhmAbs6It;30cnfo%85%|FpFE!B7XADS_Qh3}v($}7mIj1+f7aY8kc;vab z$qdUWC-gHu{5;%QAAjM&=5~?#{R<90=hL=}yYRrcy^UL{=I@7lu@@d>pFTXFTk6m6 oPipJ_Uag6omI_2Wx%V^V24C+ppEr{onEDtzUHx3vIVCg!06E(`+yDRo literal 0 HcmV?d00001 diff --git a/packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification_in_app.png b/packages/stream_chat_v1/android/app/src/main/res/drawable-xxhdpi/ic_notification_in_app.png new file mode 100644 index 0000000000000000000000000000000000000000..c0c3912a448af650c4874762742e6558a0ca2843 GIT binary patch literal 596 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2V3PK9aSW-5dwc6*?(F~pm%ynH zCf(?aSHCHADezL`UC&Dg+nBZ63VqvTB3Twam20s7blLQoBh#OUr|CBR{Qt$G*f%q zdfsQn zJ4-aslDnBv8EbhhU%i=@a2jYCNby!h_qlh4a&C$wmM+g+xYg{*ip|kYx)8C>a_XP&ti1E==f><`aB%bTDW}CvD&B4R^cg5- zX&Q6k!Fm7phgo_5t%<#-pYh>q+0^g _firebaseMessagingBackgroundHandler(RemoteMessage message) async { + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + debugPrint('[onBackgroundMessage] #firebase; message: ${message.toMap()}'); + + final data = message.data; + if (data['type'] != 'message.new') { + return; + } + String? apiKey, userId, token; + if (!kIsWeb) { + const secureStorage = FlutterSecureStorage(); + apiKey = await secureStorage.read(key: kStreamApiKey); + userId = await secureStorage.read(key: kStreamUserId); + token = await secureStorage.read(key: kStreamToken); + } + debugPrint('[onBackgroundMessage] #firebase; apiKey: $apiKey, userId: $userId, token: $token'); + if (userId == null || token == null) { + return; + } + final client = buildStreamChatClient(apiKey ?? kDefaultStreamApiKey); + final persistenceClient = StreamChatPersistenceClient(); + await persistenceClient.connect(userId); + + await client.connectUser( + User(id: userId), + token, + connectWebSocket: false, + ); + + final messageId = data['id']; + final cid = data['cid']; + final response = await client.getMessage(messageId); + debugPrint('[onBackgroundMessage] #firebase; response: $response'); + await persistenceClient.updateMessages(cid, [response.message]); + debugPrint('[onBackgroundMessage] #firebase; saved'); + +} + +Future _firebaseMessagingForegroundHandler(RemoteMessage message) async { + debugPrint('[onForegroundMessage] #firebase; message: ${message.toMap()}'); +} + +Future _firebaseMessagingOpenedHandler(RemoteMessage message) async { + debugPrint('[onOpenedMessage] #firebase; message: ${message.toMap()}'); +} + final chatPersistentClient = StreamChatPersistenceClient( logLevel: Level.SEVERE, connectionMode: ConnectionMode.regular, @@ -28,7 +81,7 @@ final chatPersistentClient = StreamChatPersistenceClient( void _sampleAppLogHandler(LogRecord record) async { if (kDebugMode) StreamChatClient.defaultLogHandler(record); - // report errors to setnry.io + // report errors to sentry.io if (record.error != null || record.stackTrace != null) { await Sentry.captureException( record.error, @@ -62,6 +115,9 @@ class _StreamChatSampleAppState extends State with SplashScreenStateMixin, TickerProviderStateMixin { final InitNotifier _initNotifier = InitNotifier(); + final firebaseSubscriptions = >[]; + StreamSubscription? userIdSubscription; + Future _initConnection() async { String? apiKey, userId, token; @@ -71,7 +127,7 @@ class _StreamChatSampleAppState extends State userId = await secureStorage.read(key: kStreamUserId); token = await secureStorage.read(key: kStreamToken); } - + debugPrint('[initConnection] #firebase; apiKey: $apiKey, userId: $userId, token: $token'); final client = buildStreamChatClient(apiKey ?? kDefaultStreamApiKey); if (userId != null && token != null) { @@ -86,6 +142,77 @@ class _StreamChatSampleAppState extends State return InitData(client, prefs); } + Future _initFirebaseMessaging(StreamChatClient client) async { + userIdSubscription?.cancel(); + userIdSubscription = client.state.currentUserStream + .map((it) => it?.id) + .distinct() + .listen((userId) async { + debugPrint('[onUserIdSet] #firebase; userId: "$userId"'); + + if (userId != null) { + FirebaseMessaging.onBackgroundMessage( + _firebaseMessagingBackgroundHandler); + firebaseSubscriptions.add(FirebaseMessaging.onMessage + .listen(_firebaseMessagingForegroundHandler)); + firebaseSubscriptions + .add(FirebaseMessaging.onMessageOpenedApp.listen((message) async { + debugPrint( + '[onOpenedMessage] #firebase; message: ${message.toMap()}'); + final channelCid = (message.data['cid'] as String?) ?? ''; + final channelType = (message.data['channel_type'] as String?) ?? ''; + final channelId = (message.data['channel_id'] as String?) ?? ''; + debugPrint('[onOpenedMessage] #firebase; channelCid; $channelCid, channelType: $channelType, channelId: $channelId'); + var channel = client.state.channels[channelCid]; + debugPrint('[onOpenedMessage] #firebase; channel1: $channel'); + if (channel == null) { + channel = client.channel( + channelId, + id: channelId, + ); + final state = await channel.watch(); + debugPrint('[onOpenedMessage] #firebase; channelState: $state'); + } + debugPrint('[onOpenedMessage] #firebase; channel2: $channel'); + + debugPrint('[onOpenedMessage] #firebase; #1'); + WidgetsBinding.instance.addPostFrameCallback((timeStamp) async { + if (channel == null) { + debugPrint('[onOpenedMessage] #firebase; rejected (channel is null)'); + return; + } + try { + debugPrint('[onOpenedMessage] #firebase; #2: ${_navigatorKey.currentContext}'); + final router = GoRouter.of(_navigatorKey.currentContext!); + debugPrint('[onOpenedMessage] #firebase; #3: $router'); + + router.pushNamed( + Routes.CHANNEL_PAGE.name, + params: Routes.CHANNEL_PAGE.params(channel), + ); + debugPrint('[onOpenedMessage] #firebase; #4'); + } catch (e, stk) { + debugPrint('[onOpenedMessage] #firebase; failed: $e; $stk'); + } + }); + + })); + firebaseSubscriptions.add( + FirebaseMessaging.instance.onTokenRefresh.listen((token) async { + debugPrint('[onTokenRefresh] #firebase; token: "$token"'); + await client.addDevice(token, PushProvider.firebase); + debugPrint('[onTokenRefresh] #firebase; token set: $token'); + })); + final token = await FirebaseMessaging.instance.getToken(); + debugPrint('[initFirebaseMessaging] #firebase; token: "$token"'); + if (token != null) { + await client.addDevice(token, PushProvider.firebase); + debugPrint('[initFirebaseMessaging] #firebase; token set: $token'); + } + } + }); + } + @override void initState() { final timeOfStartMs = DateTime.now().millisecondsSinceEpoch; @@ -100,19 +227,38 @@ class _StreamChatSampleAppState extends State if (now - timeOfStartMs > 1500) { SchedulerBinding.instance.addPostFrameCallback((timeStamp) { + debugPrint('[forwardAnimations] #firebase; context1: $context'); + debugPrint('[forwardAnimations] #firebase; _navigatorKey.currentContext1: ${_navigatorKey.currentContext}'); forwardAnimations(); + final router = GoRouter.of(_navigatorKey.currentContext!); + debugPrint('[forwardAnimations] #firebase; router1: ${router}'); }); } else { Future.delayed(const Duration(milliseconds: 1500)).then((value) { + debugPrint('[forwardAnimations] #firebase; context2: $context'); + debugPrint('[forwardAnimations] #firebase; _navigatorKey.currentContext2: ${_navigatorKey.currentContext}'); forwardAnimations(); + final router = GoRouter.of(_navigatorKey.currentContext!); + debugPrint('[forwardAnimations] #firebase; router2: ${router}'); }); } + _initFirebaseMessaging(initData.client); }, ); super.initState(); } + @override + void dispose() { + super.dispose(); + userIdSubscription?.cancel(); + for (final subscription in firebaseSubscriptions) { + unawaited(subscription.cancel()); + } + firebaseSubscriptions.clear(); + } + final GlobalKey _navigatorKey = GlobalKey(); LocalNotificationObserver? localNotificationObserver; @@ -154,6 +300,7 @@ class _StreamChatSampleAppState extends State @override Widget build(BuildContext context) { + debugPrint('[AppState.build] #firebase; context: $context'); return Stack( alignment: Alignment.center, children: [ diff --git a/packages/stream_chat_v1/lib/main.dart b/packages/stream_chat_v1/lib/main.dart index 40c5399..2211b9f 100644 --- a/packages/stream_chat_v1/lib/main.dart +++ b/packages/stream_chat_v1/lib/main.dart @@ -1,35 +1,21 @@ import 'dart:async'; +import 'package:example/app.dart'; import 'package:example/utils/app_config.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; -import 'package:firebase_core/firebase_core.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; - - -import 'package:example/app.dart'; import 'firebase_options.dart'; -@pragma('vm:entry-point') -Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { - print("#firebase; PN_2 "); - await Firebase.initializeApp(); - - // If you're going to use other Firebase services in the background, such as Firestore, - // make sure you call `initializeApp` before using other Firebase services. - print('[setupPushNotifications] newMessage: ${message.toMap()}'); -} - Future main() async { WidgetsFlutterBinding.ensureInitialized(); - print("#firebase; PN_1"); - await Firebase.initializeApp(); - Firebase.apps.forEach((it) { - print("#firebase; app: $it"); - }); - FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler); + debugPrint("#firebase; PN_1"); + await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + /// Captures errors reported by the Flutter framework. FlutterError.onError = (FlutterErrorDetails details) { if (kDebugMode) { diff --git a/packages/stream_chat_v1/lib/pages/channel_list_page.dart b/packages/stream_chat_v1/lib/pages/channel_list_page.dart index c045e0b..f4139e4 100644 --- a/packages/stream_chat_v1/lib/pages/channel_list_page.dart +++ b/packages/stream_chat_v1/lib/pages/channel_list_page.dart @@ -69,6 +69,7 @@ class _ChannelListPageState extends State { @override Widget build(BuildContext context) { + print(">>>>>>>>>> ChannelListPage"); final user = StreamChat.of(context).currentUser; if (user == null) { return const Offstage(); @@ -76,8 +77,10 @@ class _ChannelListPageState extends State { return Scaffold( backgroundColor: StreamChatTheme.of(context).colorTheme.appBg, appBar: StreamChannelListHeader( - onNewChatButtonTap: () => - GoRouter.of(context).pushNamed(Routes.NEW_CHAT.name), + onNewChatButtonTap: () { + print(">>>>>>>>>> onNewChatButtonTap"); + GoRouter.of(context).pushNamed(Routes.NEW_CHAT.name); + }, preNavigationCallback: () => FocusScope.of(context).requestFocus(FocusNode()), ), @@ -220,6 +223,7 @@ class LeftDrawer extends StatelessWidget { .withOpacity(.5), ), onTap: () { + print(">>>>>>>>>> NEW_CHAT"); Navigator.of(context).pop(); GoRouter.of(context).pushNamed(Routes.NEW_CHAT.name); }, @@ -238,6 +242,7 @@ class LeftDrawer extends StatelessWidget { .withOpacity(.5), ), onTap: () { + print(">>>>>>>>>> NEW_GROUP_CHAT"); Navigator.of(context).pop(); GoRouter.of(context).pushNamed(Routes.NEW_GROUP_CHAT.name); }, @@ -253,6 +258,7 @@ class LeftDrawer extends StatelessWidget { alignment: Alignment.bottomCenter, child: ListTile( onTap: () async { + print(">>>>>>>>>> CHOOSE_USER"); final client = StreamChat.of(context).client; final router = GoRouter.of(context); final initNotifier = context.read(); diff --git a/packages/stream_chat_v1/lib/pages/channel_page.dart b/packages/stream_chat_v1/lib/pages/channel_page.dart index e2714ee..652f266 100644 --- a/packages/stream_chat_v1/lib/pages/channel_page.dart +++ b/packages/stream_chat_v1/lib/pages/channel_page.dart @@ -47,12 +47,14 @@ class _ChannelPageState extends State { @override Widget build(BuildContext context) { + print(">>>>>>>>>> CHANNEL PAGE"); return Scaffold( backgroundColor: StreamChatTheme.of(context).colorTheme.appBg, appBar: StreamChannelHeader( showTypingIndicator: false, onBackPressed: () => GoRouter.of(context).pop(), onImageTap: () async { + print(">>>>>>>>>> onImageTap"); final channel = StreamChannel.of(context).channel; final router = GoRouter.of(context); @@ -62,6 +64,7 @@ class _ChannelPageState extends State { (element) => element.user!.id != currentUser!.id, ); if (otherUser != null) { + print(">>>>>>>>>> GROUP_INFO_SCREEN otherUser"); router.pushNamed( Routes.CHAT_INFO_SCREEN.name, params: Routes.CHAT_INFO_SCREEN.params(channel), @@ -69,6 +72,7 @@ class _ChannelPageState extends State { ); } } else { + print(">>>>>>>>>> GROUP_INFO_SCREEN"); GoRouter.of(context).pushNamed( Routes.GROUP_INFO_SCREEN.name, params: Routes.GROUP_INFO_SCREEN.params(channel), diff --git a/packages/stream_chat_v1/lib/utils/notifications_service.dart b/packages/stream_chat_v1/lib/utils/notifications_service.dart index a02d2ee..35e21a5 100644 --- a/packages/stream_chat_v1/lib/utils/notifications_service.dart +++ b/packages/stream_chat_v1/lib/utils/notifications_service.dart @@ -21,7 +21,7 @@ void showLocalNotification( if (event.message == null) return; final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); const initializationSettingsAndroid = - AndroidInitializationSettings('launch_background'); + AndroidInitializationSettings('ic_notification_in_app'); const initializationSettingsIOS = IOSInitializationSettings(); const initializationSettings = InitializationSettings( android: initializationSettingsAndroid, @@ -33,6 +33,8 @@ void showLocalNotification( await flutterLocalNotificationsPlugin.initialize( initializationSettings, onSelectNotification: (channelCid) async { + debugPrint("[onSelectNotification] #firebase; channelCid: $channelCid"); + debugPrint("[onSelectNotification] #firebase; context: $context"); if (channelCid != null) { final client = StreamChat.of(context).client; final router = GoRouter.of(context);