- Я использую Firebase Cloud Messaging (FCM) в своем приложении Flutter и
пытаюсь добиться следующего: - Воспроизведение специального звука уведомления при получении уведомления.
Перенаправление на определенный экран при нажатии на уведомление, даже
если приложение закрыто или не запускается. фон.
- Проблема со специальным звуком:
- Когда я включаю объект notification в полезную нагрузку, уведомление воспроизводит
звук по умолчанию вместо пользовательского звука. - Если я включу и уведомление, и пользовательский звук конфигурации звука в разделе android
, я получаю два уведомления:
одно с звук по умолчанию. - Другой с собственным звуком.
- Когда я включаю объект notification в полезную нагрузку, уведомление воспроизводит
- Перенаправление Проблема:
- Когда я удаляю объект уведомление и полностью полагаюсь на данные объект,
специальный звук работает, но перенаправление не выполняется, если приложение закрыто или находится вне
фонового режима. - В таких случаях приложение не получает событие нажатия на уведомление.
- Когда я удаляю объект уведомление и полностью полагаюсь на данные объект,
Код: Выделить всё
Below is the payload I'm sending to FCM:
{
"message": {
"token": "DEVICE_FCM_TOKEN",
"notification": {
"title": "Visitor has been admitted!",
"body": "Dhaval developer (Visitor) has been admitted.",
},
"android": {
"notification": {
"sound": "visitor_notification_sound"
}
},
"apns":{
"payload":{
"aps":{
"sound":"visitor_notification_sound.mp3"
}
}
},
"data": {
"id": "1215454",
"notification_type": "visitor_visited",
"other_data_key": "other_data_value"
}
}
}
- С уведомление объект:
- Перенаправление работает, даже если приложение закрыто или не находится в фоновом режиме.
- В уведомлении воспроизводится звук по умолчанию, а не пользовательский звук.
- Без уведомления объект:
- Пользовательский звук работает нормально.
- Перенаправление не выполняется, когда приложение закрывается или находится вне фонового режима (события щелчка
не получены ).
- В том числе как уведомление, и собственный звук в разделе android :
- Получено два уведомления :
Один с звуком по умолчанию. - Другой с собственным звуком. сильный>
- Получено два уведомления :
Вот как я обрабатываю уведомления в своем приложении Flutter:
main.dart
Код: Выделить всё
import 'package:flutter/material.dart';
import 'package:notification_demo/fcm_controller.dart';
import 'package:notification_demo/firebase_options.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
await FirebaseCloudMessagingService().initFCM();
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State createState() => _MyAppState();
}
class _MyAppState extends State {
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: Scaffold(
body: Center(
child: Text('hello'),
),
),
);
}
}
Код: Выделить всё
import 'dart:convert';
import 'dart:developer';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'dart:math' as math;
import 'package:notification_demo/firebase_options.dart';
@pragma('vm:entry-point')
Future notificationTapBackground(NotificationResponse notificationResponse) async {
debugPrint('background notification tap');
}
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
@pragma('vm:entry-point')
Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
debugPrint("Handling a background message ${message.messageId}");
if (message.messageId != null && message.messageId!.isNotEmpty) {
FirebaseCloudMessagingService.showNotification(message);
}
}
class FirebaseCloudMessagingService {
Future initFCM() async {
debugPrint('DDDD initFCM');
try {
await _requestPermission();
await _initNotificationInfo();
String deviceToken = await _getToken() ?? '';
debugPrint('FCM Token: $deviceToken');
await _setupMessageHandlers();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
} catch (e) {
log("Exception: $e");
}
}
Future _requestPermission() async {
NotificationSettings settings = await FirebaseMessaging.instance.requestPermission(
alert: true,
announcement: true,
badge: true,
carPlay: true,
criticalAlert: true,
provisional: true,
sound: true,
);
debugPrint('Permission status: ${settings.authorizationStatus}');
}
Future _initNotificationInfo() async {
var initializationSettingAndroid = const AndroidInitializationSettings('@mipmap/ic_launcher');
const DarwinInitializationSettings initializationSettingIOS = DarwinInitializationSettings();
var initializationSettings = InitializationSettings(android: initializationSettingAndroid, iOS: initializationSettingIOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings, onDidReceiveNotificationResponse: (NotificationResponse notificationResponse) async {
handleNotificationTappedFormNotificationTray(jsonDecode(notificationResponse.payload ?? "{}"));
}, onDidReceiveBackgroundNotificationResponse: notificationTapBackground);
}
Future _getToken() async {
try {
return await FirebaseMessaging.instance.getToken();
} catch (e) {
debugPrint("Error fetching token: $e");
return null;
}
}
Future _setupMessageHandlers() async {
FirebaseMessaging.onMessage.listen((RemoteMessage message) async {
showNotification(message);
});
FirebaseMessaging.onMessageOpenedApp.listen((event) async {
await handleNotificationTappedFormNotificationTray(event.data);
});
}
static Future showNotification(RemoteMessage message) async {
String title = message.data['title'] ?? '';
String body = message.data['body'] ?? '';
String soundName = 'notification_sound_android';
String iosSoundName = 'notification_sound_android.mp3';
if (message.data['notification_type'] == 'visitor_visited') {
soundName = 'visitor_notification_sound';
iosSoundName = 'visitor_notification_sound.mp3';
}
AndroidNotificationChannel channel = AndroidNotificationChannel(
soundName,
'General Notifications',
importance: Importance.max,
playSound: true,
sound: RawResourceAndroidNotificationSound(soundName),
);
AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails(
channel.id,
channel.name,
sound: RawResourceAndroidNotificationSound(soundName),
);
NotificationDetails notificationDetails = NotificationDetails(
android: androidNotificationDetails,
iOS: DarwinNotificationDetails(sound: iosSoundName),
);
flutterLocalNotificationsPlugin.show(
math.Random().nextInt(100000),
title,
body,
notificationDetails,
payload: jsonEncode(message.data),
);
}
Future handleNotificationTappedFormNotificationTray(Map notificationData) async {
debugPrint('Notification tapped: $notificationData');
// Implement redirection logic here
}
}
Как настроить FCM и обрабатывать уведомления во Flutter, чтобы:
- Пользовательский звук воспроизводится без включения звука по умолчанию или дублирования
уведомлений. - При нажатии на уведомление происходит перенаправление на определенный экран. , даже если приложение
закрыто или не работает в фоновом режиме. - Отображается только одно уведомление.
Подробнее здесь: https://stackoverflow.com/questions/793 ... fails-when