feat(notification): handle notification onclick event

This commit is contained in:
anhtunz
2025-04-08 10:21:48 +07:00
parent 725d35aa5b
commit d4a6e236a0
4 changed files with 45 additions and 27 deletions

View File

@@ -225,8 +225,7 @@ class _DevicesManagerScreenState extends State<DevicesManagerScreen> {
void getUserRole() async { void getUserRole() async {
role = await apiServices.getUserRole(); role = await apiServices.getUserRole();
devicesManagerBloc.sinkUserRole.add(role);F: devicesManagerBloc.sinkUserRole.add(role);
cd
} }
double getTableHeight(int dataLength){ double getTableHeight(int dataLength){

View File

@@ -2,12 +2,15 @@
import 'dart:developer'; import 'dart:developer';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:badges/badges.dart' as badges; import 'package:badges/badges.dart' as badges;
import 'package:persistent_bottom_nav_bar/persistent_bottom_nav_bar.dart'; import 'package:persistent_bottom_nav_bar/persistent_bottom_nav_bar.dart';
import '../../product/permission/notification_permission.dart'; import '../../product/permission/notification_permission.dart';
import '../../product/services/notification_services.dart';
import '../settings/profile/profile_model.dart'; import '../settings/profile/profile_model.dart';
import '../../product/extension/context_extension.dart'; import '../../product/extension/context_extension.dart';
import '../../bloc/home_bloc.dart'; import '../../bloc/home_bloc.dart';
@@ -41,8 +44,22 @@ class MainScreen extends StatefulWidget {
State<MainScreen> createState() => _MainScreenState(); State<MainScreen> createState() => _MainScreenState();
} }
PersistentTabController controller = PersistentTabController(initialIndex: 0);
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
log("Full background message payload: ${message.toMap()}");
await Firebase.initializeApp();
final notificationServices = NotificationServices();
await notificationServices.initLocalNotifications(controller);
await notificationServices.showNotification(message);
log("Background message handled: ${message.data['title']}");
}
class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver { class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
APIServices apiServices = APIServices(); APIServices apiServices = APIServices();
final NotificationServices notificationServices = NotificationServices();
late MainBloc mainBloc; late MainBloc mainBloc;
bool isVN = true; bool isVN = true;
bool isLight = true; bool isLight = true;
@@ -81,6 +98,9 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
initialCheck(); initialCheck();
getBellNotification(); getBellNotification();
mainBloc.getUserProfile(); mainBloc.getUserProfile();
notificationServices.initLocalNotifications(controller);
notificationServices.firebaseInit(context);
NotificationServices().setupInteractMessage(controller);
} }
@override @override
@@ -104,7 +124,7 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
WidgetsBinding.instance.removeObserver(this); WidgetsBinding.instance.removeObserver(this);
} }
PersistentTabController controller = PersistentTabController(initialIndex: 0);
List<PersistentBottomNavBarItem> _navBarsItems() { List<PersistentBottomNavBarItem> _navBarsItems() {
return [ return [
PersistentBottomNavBarItem( PersistentBottomNavBarItem(
@@ -180,10 +200,6 @@ class _MainScreenState extends State<MainScreen> with WidgetsBindingObserver {
child: const InterFamilyScreen(), child: const InterFamilyScreen(),
blocBuilder: () => InterFamilyBloc(), blocBuilder: () => InterFamilyBloc(),
), ),
/*BlocProvider(
child: const NotificationScreen(),
blocBuilder: () => NotificationBloc(),
),*/
]; ];
} }

View File

@@ -4,7 +4,8 @@ import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:sfm_app/product/services/api_services.dart'; import 'feature/main/main_screen.dart';
import 'product/services/api_services.dart';
import 'product/services/notification_services.dart'; import 'product/services/notification_services.dart';
import 'product/services/theme_services.dart'; import 'product/services/theme_services.dart';
import 'product/services/language_services.dart'; import 'product/services/language_services.dart';
@@ -16,8 +17,8 @@ void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(); await Firebase.initializeApp();
FirebaseMessaging FirebaseMessaging
.onBackgroundMessage(_firebaseMessagingBackgroundHandler); .onBackgroundMessage(firebaseMessagingBackgroundHandler);
NotificationServices().setupInteractMessage(); // NotificationServices().setupInteractMessage();
runApp( runApp(
BlocProvider( BlocProvider(
@@ -27,15 +28,15 @@ void main() async {
); );
} }
@pragma('vm:entry-point') // @pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async { // Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
log("Full background message payload: ${message.toMap()}"); // log("Full background message payload: ${message.toMap()}");
await Firebase.initializeApp(); // await Firebase.initializeApp();
final notificationServices = NotificationServices(); // final notificationServices = NotificationServices();
await notificationServices.initLocalNotifications(); // await notificationServices.initLocalNotifications();
await notificationServices.showNotification(message); // await notificationServices.showNotification(message);
log("Background message handled: ${message.data['title']}"); // log("Background message handled: ${message.data['title']}");
} // }
class MyApp extends StatefulWidget { class MyApp extends StatefulWidget {
const MyApp({super.key}); const MyApp({super.key});
@@ -73,8 +74,8 @@ class _MyAppState extends State<MyApp> {
void initState() { void initState() {
super.initState(); super.initState();
mainBloc = BlocProvider.of(context); mainBloc = BlocProvider.of(context);
notificationServices.initLocalNotifications(); // notificationServices.initLocalNotifications();
notificationServices.firebaseInit(context); // notificationServices.firebaseInit(context);
// notificationServices.setupInteractMessage(); // notificationServices.setupInteractMessage();
notificationServices.getDeviceToken().then((token){ notificationServices.getDeviceToken().then((token){
print("Firebase Token: $token"); print("Firebase Token: $token");

View File

@@ -3,12 +3,13 @@ import 'dart:math' as math;
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:persistent_bottom_nav_bar/persistent_bottom_nav_bar.dart';
class NotificationServices { class NotificationServices {
FirebaseMessaging messaging = FirebaseMessaging.instance; FirebaseMessaging messaging = FirebaseMessaging.instance;
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
Future<void> initLocalNotifications() async { Future<void> initLocalNotifications(PersistentTabController controller) async {
const AndroidInitializationSettings androidInitializationSettings = AndroidInitializationSettings('@mipmap/ic_launcher'); const AndroidInitializationSettings androidInitializationSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
const DarwinInitializationSettings iosInitializationSettings = DarwinInitializationSettings(); const DarwinInitializationSettings iosInitializationSettings = DarwinInitializationSettings();
const InitializationSettings initializationSettings = InitializationSettings( const InitializationSettings initializationSettings = InitializationSettings(
@@ -20,7 +21,7 @@ class NotificationServices {
initializationSettings, initializationSettings,
onDidReceiveNotificationResponse: (NotificationResponse response) { onDidReceiveNotificationResponse: (NotificationResponse response) {
dev.log("Người dùng click thông báo ở foreground với payload: ${response.payload}"); dev.log("Người dùng click thông báo ở foreground với payload: ${response.payload}");
handleMessage(response.payload); handleMessage(response.payload,controller);
}, },
); );
dev.log("Local notifications initialized"); dev.log("Local notifications initialized");
@@ -126,18 +127,19 @@ class NotificationServices {
} }
} }
void handleMessage(String? payload) { void handleMessage(String? payload, PersistentTabController controller) {
dev.log("Handling notification tap with payload: $payload"); dev.log("Handling notification tap with payload: $payload");
controller.jumpToTab(1);
} }
Future<void> setupInteractMessage() async { Future<void> setupInteractMessage(PersistentTabController controller) async {
// Khi app terminated // Khi app terminated
RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage(); RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) { if (initialMessage != null) {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
try { try {
handleMessage(initialMessage.data['type']); handleMessage(initialMessage.data['type'],controller);
} catch (e, stack) { } catch (e, stack) {
dev.log("Error handling initial message: $e\n$stack"); dev.log("Error handling initial message: $e\n$stack");
} }
@@ -146,7 +148,7 @@ class NotificationServices {
// Khi app ở background // Khi app ở background
FirebaseMessaging.onMessageOpenedApp.listen((message) { FirebaseMessaging.onMessageOpenedApp.listen((message) {
try { try {
handleMessage(message.data['type']); handleMessage(message.data['type'],controller);
} catch (e, stack) { } catch (e, stack) {
dev.log("Error in onMessageOpenedApp: $e\n$stack"); dev.log("Error in onMessageOpenedApp: $e\n$stack");
} }