Anonymous
Мое уведомление не работает, когда приложение было закрыто или закрыто.
Сообщение
Anonymous » 11 ноя 2024, 15:51
Может ли кто-нибудь помочь мне в моем проекте в приложении Flutter для Android, потому что моя основная проблема заключалась в том, что push-уведомление и я использую FCM, потому что я использую Firebase для базы данных, и проблема в том, что уведомления не работают, когда приложение было закрыто или закрыто что мне нужно войти в систему, чтобы получить уведомление.
вот основной код:
Код: Выделить всё
// 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.');
}
}
Я пытался посмотреть документацию на YouTube, но все равно не помогло. Моя основная проблема
Подробнее здесь:
https://stackoverflow.com/questions/791 ... -or-closed
1731329494
Anonymous
Может ли кто-нибудь помочь мне в моем проекте в приложении Flutter для Android, потому что моя основная проблема заключалась в том, что push-уведомление и я использую FCM, потому что я использую Firebase для базы данных, и проблема в том, что уведомления не работают, когда приложение было закрыто или закрыто что мне нужно войти в систему, чтобы получить уведомление. вот основной код: [code]// 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); } [/code] вот код службы уведомлений: [code]// 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); } } [/code] вот код уведомления: [code]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.'); } } [/code] Я пытался посмотреть документацию на YouTube, но все равно не помогло. Моя основная проблема Подробнее здесь: [url]https://stackoverflow.com/questions/79177714/my-notification-doesnt-work-when-the-app-was-terminated-or-closed[/url]