157 lines
5.5 KiB
Dart
157 lines
5.5 KiB
Dart
import 'dart:developer' as dev;
|
|
import 'dart:math' as math;
|
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|
|
|
class NotificationServices {
|
|
FirebaseMessaging messaging = FirebaseMessaging.instance;
|
|
final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
|
|
|
|
Future<void> initLocalNotifications() async {
|
|
const AndroidInitializationSettings androidInitializationSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
|
|
const DarwinInitializationSettings iosInitializationSettings = DarwinInitializationSettings();
|
|
const InitializationSettings initializationSettings = InitializationSettings(
|
|
android: androidInitializationSettings,
|
|
iOS: iosInitializationSettings,
|
|
);
|
|
|
|
await _flutterLocalNotificationsPlugin.initialize(
|
|
initializationSettings,
|
|
onDidReceiveNotificationResponse: (NotificationResponse response) {
|
|
dev.log("Người dùng click thông báo ở foreground với payload: ${response.payload}");
|
|
handleMessage(response.payload);
|
|
},
|
|
);
|
|
dev.log("Local notifications initialized");
|
|
}
|
|
|
|
void firebaseInit(BuildContext context) {
|
|
FirebaseMessaging.onMessage.listen((message) {
|
|
dev.log("Foreground message payload: ${message.toMap()}");
|
|
if (WidgetsBinding.instance != null) {
|
|
showNotification(message);
|
|
} else {
|
|
dev.log("App is in background, skipping foreground notification");
|
|
}
|
|
});
|
|
}
|
|
|
|
Future<String> getDeviceToken() async {
|
|
String? token = await messaging.getToken();
|
|
return token!;
|
|
}
|
|
|
|
void isTokenRefresh() {
|
|
messaging.onTokenRefresh.listen((newToken) {
|
|
dev.log("Refresh Firebase Messaging Token: $newToken");
|
|
});
|
|
}
|
|
|
|
Future<void> showNotification(RemoteMessage message) async {
|
|
String? title = message.data['title'];
|
|
String? body = message.data['body'];
|
|
String type = message.data['type'] ?? "normal";
|
|
|
|
if (title == null || body == null) {
|
|
dev.log("Skipping notification due to missing title or body");
|
|
return;
|
|
}
|
|
|
|
AndroidNotificationChannel androidNotificationChannel = AndroidNotificationChannel(
|
|
math.Random.secure().nextInt(1000000).toString(),
|
|
'High Importance Notification',
|
|
importance: Importance.max,
|
|
);
|
|
|
|
final androidPlugin = _flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>();
|
|
await androidPlugin?.deleteNotificationChannel(androidNotificationChannel.id);
|
|
|
|
AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails(
|
|
androidNotificationChannel.id,
|
|
androidNotificationChannel.name,
|
|
channelDescription: "Channel description",
|
|
sound: getSound(type),
|
|
importance: androidNotificationChannel.importance,
|
|
priority: Priority.high,
|
|
ticker: 'ticker',
|
|
actions: type == "smoke_warning"
|
|
? [
|
|
const AndroidNotificationAction(
|
|
"id1",
|
|
"Hogg xóa được",
|
|
// true thì khi nhấn vào button sẽ mở giao diện ra
|
|
showsUserInterface: true,
|
|
cancelNotification: false,
|
|
)
|
|
]
|
|
: null
|
|
);
|
|
|
|
const DarwinNotificationDetails darwinNotificationDetails = DarwinNotificationDetails(
|
|
presentAlert: true,
|
|
presentBadge: true,
|
|
presentBanner: true,
|
|
presentSound: true,
|
|
);
|
|
|
|
NotificationDetails notificationDetails = NotificationDetails(
|
|
android: androidNotificationDetails,
|
|
iOS: darwinNotificationDetails,
|
|
);
|
|
|
|
// Truyền payload vào thông báo
|
|
String payload = message.data['type'] ?? "default";
|
|
await _flutterLocalNotificationsPlugin.show(
|
|
math.Random.secure().nextInt(1000000),
|
|
title,
|
|
body,
|
|
notificationDetails,
|
|
payload: payload,
|
|
);
|
|
dev.log("Displayed notification with title: $title, body: $body, type: $type");
|
|
}
|
|
|
|
AndroidNotificationSound getSound(String type) {
|
|
if (type == "welcome") {
|
|
return const RawResourceAndroidNotificationSound("welcome");
|
|
} else if (type == "success") {
|
|
return const RawResourceAndroidNotificationSound("success_alert");
|
|
} else if (type == "smoke_warning") {
|
|
return const RawResourceAndroidNotificationSound("warning_alarm");
|
|
} else if (type == "battery_warning") {
|
|
return const RawResourceAndroidNotificationSound("new_alarm");
|
|
} else {
|
|
return const RawResourceAndroidNotificationSound("normal");
|
|
}
|
|
}
|
|
|
|
void handleMessage(String? payload) {
|
|
dev.log("Handling notification tap with payload: $payload");
|
|
// Thêm logic xử lý khi nhấn thông báo ở đây
|
|
// Ví dụ: Điều hướng màn hình hoặc xử lý dữ liệu
|
|
}
|
|
|
|
Future<void> setupInteractMessage() async {
|
|
// Khi app terminated
|
|
RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
|
|
|
|
if (initialMessage != null) {
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
try {
|
|
handleMessage(initialMessage.data['type']);
|
|
} catch (e, stack) {
|
|
dev.log("Error handling initial message: $e\n$stack");
|
|
}
|
|
});
|
|
}
|
|
// Khi app ở background
|
|
FirebaseMessaging.onMessageOpenedApp.listen((message) {
|
|
try {
|
|
handleMessage(message.data['type']);
|
|
} catch (e, stack) {
|
|
dev.log("Error in onMessageOpenedApp: $e\n$stack");
|
|
}
|
|
});
|
|
}
|
|
} |