вот основной код:
Код: Выделить всё
// main.dart
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'login_screen.dart';
import 'notification_service.dart';
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
final NotificationService notificationService = NotificationService();
Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(); // Ensure Firebase is initialized in the background
notificationService.showNotification(
message.data['title'],
message.data['body'],
);
print("Handling a background message: ${message.messageId}");
}
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Register background message handler
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
// Initialize local notifications
initializeLocalNotifications();
// Sign in for notifications in the main app lifecycle
await _signInForNotifications();
// Get FCM token and save to Firebase
await _initializeFCMToken();
runApp(const FireGuard());
}
class FireGuard extends StatelessWidget {
const FireGuard({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'FireGuard Fire Safety',
theme: ThemeData(
primarySwatch: Colors.red,
),
home: const LoginScreen(),
);
}
}
Future _signInForNotifications() async {
try {
await FirebaseAuth.instance.signInWithEmailAndPassword(
email: "",
password: "",
);
print("Signed in for notifications.");
} catch (e) {
print("Failed to sign in for notifications: $e");
}
}
Future _initializeFCMToken() async {
// Request permissions for notifications on iOS
FirebaseMessaging messaging = FirebaseMessaging.instance;
await messaging.requestPermission();
// Get the FCM token
String? token = await messaging.getToken();
if (token != null) {
await _saveTokenToNotificationNode(token);
}
// Listen for token refreshes and save new token if it changes
FirebaseMessaging.instance.onTokenRefresh.listen(_saveTokenToNotificationNode);
}
Future _saveTokenToNotificationNode(String token) async {
final DatabaseReference notificationRef =
FirebaseDatabase.instance.ref().child("notifications");
// Save the FCM token directly as the key in the notifications node
await notificationRef.child(token).set({
"FCMToken": token,
"isActive": true, // Optional field to indicate the token's status
});
print("Token saved to notifications node in Firebase with token $token");
}
void initializeLocalNotifications() async {
const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher');
const InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
Код: Выделить всё
// notification_service.dart
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:vibration/vibration.dart';
import 'main.dart'; // Import for flutterLocalNotificationsPlugin
class NotificationService {
final FirebaseMessaging _messaging = FirebaseMessaging.instance;
NotificationService() {
_initializeFCM();
}
// Initialize FCM
void _initializeFCM() async {
// Request notification permissions and subscribe to topics
NotificationSettings settings = await _messaging.requestPermission(
alert: true,
announcement: true,
badge: true,
carPlay: false,
criticalAlert: true,
provisional: false,
sound: true,
);
print('User granted permission: ${settings.authorizationStatus}');
await _messaging.subscribeToTopic('fire_alerts');
// FirebaseMessaging.onMessage.listen((RemoteMessage message) {
// if (message.notification != null) {
// showNotification(
// message.data['title'] ?? 'Notification',
// message.data['body'] ?? 'You have a new message.',
// );
// }
// });
// Handle background messages
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
// _handleNotificationClick(message.data);
showNotification(
message.data['title'] ?? 'Notification',
message.data['body'] ?? 'You have a new message.',
);
});
}
// Public method to display any notification
void showNotification(String title, String body, {bool vibrate = false}) async {
const AndroidNotificationDetails androidPlatformChannelSpecifics = AndroidNotificationDetails(
'your_channel_id',
'Your Channel Name',
channelDescription: 'Your Channel Description',
importance: Importance.max,
priority: Priority.high,
showWhen: true,
);
const NotificationDetails platformChannelSpecifics = NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0,
title,
body,
platformChannelSpecifics,
);
// Optionally trigger vibration if supported
if (vibrate && (await Vibration.hasVibrator() ?? false)) {
Vibration.vibrate(duration: 500); // 500 ms vibration
}
}
// Save the FCM token (customize if needed for Firebase)
Future _saveTokenToFirebase(String token) async {
print("FCM Token saved: $token");
}
// Public method to send a system notification
void sendSystemNotification(String title, String body, {bool vibrate = true}) {
showNotification(title, body, vibrate: vibrate);
}
}
Код: Выделить всё
import 'package:fireguard/notification_service.dart';
import 'package:flutter/material.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:intl/intl.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_phone_direct_caller/flutter_phone_direct_caller.dart';
import 'package:vibration/vibration.dart';
class DashboardNotification extends StatefulWidget {
final String username;
const DashboardNotification({super.key, required this.username});
@override
_DashboardNotificationState createState() => _DashboardNotificationState();
}
class _DashboardNotificationState extends State {
String? macAddress;
DateTime? loginTime;
final DatabaseReference _clientAccountsRef =
FirebaseDatabase.instance.ref().child("Client Accounts");
final DatabaseReference _devicesRef =
FirebaseDatabase.instance.ref().child("devices");
final NotificationService _notificationService = NotificationService();
List _fireNotifications = [];
final Map _lastNotifiedTimestamp = {};
@override
void initState() {
super.initState();
loginTime = DateTime.now();
// _initializeFCM(); // Initialize FCM for notifications
_loadUserDevicesAndFireHistory();
//initializeNotifications();
}
Future _saveLastNotifiedTimestamps() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List timestamps = _lastNotifiedTimestamp.entries
.map((entry) => "${entry.key}:${entry.value}")
.toList();
await prefs.setStringList('lastNotifiedTimestamps', timestamps);
}
void _sendSystemNotification(String macAddress, String fireTimestamp, String severityLevel) {
final DateTime now = DateTime.now();
final DateTime fireEventTime = DateFormat('MM/dd/yyyy hh:mm:ss a').parse(fireTimestamp);
// Check if the fire event is after the login time to avoid old events triggering notifications
if (fireEventTime.isAfter(loginTime!)) {
final DateTime? lastNotified = _lastNotifiedTimestamp[macAddress] != null
? DateFormat('MM/dd/yyyy hh:mm:ss a').parse(_lastNotifiedTimestamp[macAddress]!)
: null;
// Set a cooldown period (5 minutes)
const int cooldownPeriodInSeconds = 300;
if (lastNotified == null || now.difference(lastNotified).inSeconds > cooldownPeriodInSeconds) {
// Use NotificationService to send the notification with vibration
_notificationService.sendSystemNotification(
'Fire Detected! - Severity Level: $severityLevel',
'Fire detected in device: $macAddress at $fireTimestamp ',
vibrate: true,
);
// Update the last notified timestamp for the device
_lastNotifiedTimestamp[macAddress] = DateFormat('MM/dd/yyyy hh:mm:ss a').format(now);
// Save the last notified timestamps to shared preferences
_saveLastNotifiedTimestamps();
} else {
print('Notification suppressed to prevent duplicates (Cooldown in effect)');
}
} else {
print('Notification suppressed as fire event occurred before login.');
}
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... -or-closed