diff --git a/apps/mobile_app/lib/core/notifications_init.dart b/apps/mobile_app/lib/core/notifications_init.dart index 8fefd6d5..9da47413 100644 --- a/apps/mobile_app/lib/core/notifications_init.dart +++ b/apps/mobile_app/lib/core/notifications_init.dart @@ -3,6 +3,8 @@ import 'dart:convert'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:navigation/navigation.dart'; +import 'package:sf_app_platform/navigation/app_router.dart'; /// Background message handler. MUST be a top-level function annotated with /// `@pragma('vm:entry-point')` so the Flutter engine can dispatch it from a @@ -15,9 +17,9 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart'; /// isolate. @pragma('vm:entry-point') Future firebaseMessagingBackgroundHandler(RemoteMessage message) async { - debugPrint( - '[FCM-bg] message received: ${message.messageId} - ${message.notification?.title}', - ); + debugPrint('[FCM-bg] messageId: ${message.messageId}'); + debugPrint('[FCM-bg] notification: title=${message.notification?.title}, body=${message.notification?.body}'); + debugPrint('[FCM-bg] data: ${message.data}'); } const String _localChannelId = 'sf_default_channel'; @@ -96,9 +98,9 @@ Future _initLocalNotifications() async { } void _onForegroundMessage(RemoteMessage message) { - debugPrint( - '[FCM-fg] message received: ${message.messageId} - ${message.notification?.title}', - ); + debugPrint('[FCM-fg] messageId: ${message.messageId}'); + debugPrint('[FCM-fg] notification: title=${message.notification?.title}, body=${message.notification?.body}'); + debugPrint('[FCM-fg] data: ${message.data}'); final notification = message.notification; if (notification == null) return; @@ -128,15 +130,39 @@ void _onForegroundMessage(RemoteMessage message) { } void _onMessageOpenedApp(RemoteMessage message) { - debugPrint( - '[FCM-tap] user tapped notification: ${message.messageId} - data: ${message.data}', - ); - // TODO: handle deep linking based on message.data. + debugPrint('[FCM-tap] messageId: ${message.messageId}'); + debugPrint('[FCM-tap] notification: title=${message.notification?.title}, body=${message.notification?.body}'); + debugPrint('[FCM-tap] data: ${message.data}'); + _handleNotificationNavigation(message.data); } void _onLocalNotificationTapped(NotificationResponse response) { - debugPrint( - '[FCM-localtap] user tapped local notification: id=${response.id} payload=${response.payload}', - ); - // TODO: handle deep linking. Payload contains JSON-encoded message.data. + debugPrint('[LocalNotif-tap] id=${response.id}'); + debugPrint('[LocalNotif-tap] payload=${response.payload}'); + debugPrint('[LocalNotif-tap] actionId=${response.actionId}'); + + final payload = response.payload; + if (payload == null || payload.isEmpty) return; + + try { + final data = jsonDecode(payload) as Map; + _handleNotificationNavigation(data); + } catch (e) { + debugPrint('[LocalNotif-tap] failed to parse payload: $e'); + } +} + +void _handleNotificationNavigation(Map data) { + final currentLocation = + appRouter.routerDelegate.currentConfiguration.uri.path; + if (!currentLocation.startsWith(AppRoutes.legacyDashboard)) return; + + final command = data['command'] as String?; + + switch (command) { + case 'ALERT': + appRouter.go(AppRoutes.deviceAlertsNotifications); + default: + debugPrint('[Notification] unhandled command: $command'); + } }