I am using flutter awesome notifications and when ever i send notification from firebase or notification sent from my custom backend i receive two notifications one without action button and one with action button i also tried to remove the action button to check if this is causing the issue but still getting same duplicate notifications
here is my main.dart file where i have done notification initialization:
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
if (message.notification != null) {
// log(message.data["notification_id"]);
NotificationService.showNotification(
title: message.notification!.title!,
body: message.notification!.body!,
actionButtons: actionButtons);
}
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
}
GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
final actionButtons = [
NotificationActionButton(
key: 'Verify',
label: 'Confirm Now',
enabled: true,
),
];
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final id = await cGetDeviceId();
CommonData.deviceId = id;
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
await NotificationService.initializeNotification();
FirebaseMessaging messagingg = FirebaseMessaging.instance;
FirebaseMessaging.instance.getInitialMessage().then((value) {
if (value?.notification != null) {
// log(value!.data["notification_id"]);
NotificationService.showNotification(
title: value!.notification!.title!,
body: value.notification!.body!,
actionButtons: actionButtons);
}
});
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await messagingg.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
sound: true,
);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (message.notification != null) {
// log(message.data["notification_id"]);
NotificationService.showNotification(
title: message.notification!.title!,
body: message.notification!.body!,
actionButtons: actionButtons);
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
if (message.notification != null) {
// log(message.data["notification_id"]);
NotificationService.showNotification(
title: message.notification!.title!,
body: message.notification!.body!,
actionButtons: actionButtons);
}
});
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider<LoadingManagemet>(
create: (context) => LoadingManagemet(),
),
ChangeNotifierProvider<ParkingRemindersSingleton>(
create: (context) => ParkingRemindersSingleton(),
),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Ay Caramba',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const SplashScreen(),
));
}
}
Here is my notification services files :
import 'dart:developer';
import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:flutter/material.dart';
class NotificationService {
static Future<void> initializeNotification() async {
await AwesomeNotifications().initialize(
null,
[
NotificationChannel(
channelGroupKey: 'high_importance_channel',
channelKey: 'high_importance_channel',
channelName: 'Basic notifications',
channelDescription: 'Notification channel for basic tests',
defaultColor: const Color(0xFF9D50DD),
ledColor: Colors.white,
importance: NotificationImportance.Max,
channelShowBadge: true,
onlyAlertOnce: true,
playSound: true,
criticalAlerts: true,
)
],
channelGroups: [
NotificationChannelGroup(
channelGroupKey: 'high_importance_channel_group',
channelGroupName: 'Group 1',
)
],
debug: true,
);
await AwesomeNotifications().isNotificationAllowed().then(
(isAllowed) async {
if (!isAllowed) {
await AwesomeNotifications().requestPermissionToSendNotifications();
}
},
);
await AwesomeNotifications().setListeners(
onActionReceivedMethod: onActionReceivedMethod,
onNotificationCreatedMethod: onNotificationCreatedMethod,
onNotificationDisplayedMethod: onNotificationDisplayedMethod,
onDismissActionReceivedMethod: onDismissActionReceivedMethod,
);
}
/// Use this method to detect when a new notification or a schedule is created
static Future<void> onNotificationCreatedMethod(
ReceivedNotification receivedNotification) async {
debugPrint('onNotificationCreatedMethod');
}
/// Use this method to detect every time that a new notification is displayed
static Future<void> onNotificationDisplayedMethod(
ReceivedNotification receivedNotification) async {
debugPrint('onNotificationDisplayedMethod');
}
/// Use this method to detect if the user dismissed a notification
static Future<void> onDismissActionReceivedMethod(
ReceivedAction receivedAction) async {
debugPrint('onDismissActionReceivedMethod');
}
/// Use this method to detect when the user taps on a notification or action button
static Future<void> onActionReceivedMethod(
ReceivedAction receivedAction) async {
debugPrint('onActionReceivedMethod');
final payload = receivedAction.toString();
// final notificationId = payload['notification_id'];
log('Notification ID: $payload');
}
static Future<void> showNotification({
required final String title,
required final String body,
final String? summary,
final Map<String, String>? payload,
final ActionType actionType = ActionType.Default,
final NotificationLayout notificationLayout = NotificationLayout.Default,
final NotificationCategory? category,
final String? bigPicture,
final List<NotificationActionButton>? actionButtons,
final bool scheduled = false,
final int? interval,
}) async {
assert(!scheduled || (scheduled && interval != null));
await AwesomeNotifications().createNotification(
content: NotificationContent(
id: -1,
channelKey: 'high_importance_channel',
title: title,
body: body,
actionType: actionType,
notificationLayout: notificationLayout,
summary: summary,
category: category,
payload: payload,
bigPicture: bigPicture,
),
actionButtons: actionButtons,
schedule: scheduled
? NotificationInterval(
interval: interval,
timeZone:
await AwesomeNotifications().getLocalTimeZoneIdentifier(),
preciseAlarm: true,
)
: null,
);
}
}
I need help to resolve this and want to achieve like when user click on action button the notification_id logged onto the console so i will use that to utilize in API hitting.
2
Answers
I have same issue with that i think in background the awesome notification automatically handle to send notification that’s why you are getting two notification first is which handled by awesome notification and second is which handle by you in firebase onbackground message handler and till now i have not find any solution with that.
If you set the
notification
key in the payload of the notification you are sending, you are creating what the FCM docs refer to as a "notification message" aka a "display message". When your app is running in the background the FCM SDK will handle displaying of the notification to the user. This is probably the notification without the action buttons that you are seeing.You are also creating another notification (the one with action buttons) when this notification arrives with the call to
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler)
.If instead of a "Notification Message" you send a "data message", the FCM SDK will leave all the handling of the incoming notification to your app code.
The difference between the content of two types of messages is as follows
See the docs here https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages