skip to Main Content

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


  1. 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.

    Login or Signup to reply.
  2. 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.

    With FCM, you can send two types of messages to clients:

    · Notification messages, sometimes thought of as "display messages." These are handled by the FCM SDK automatically.

    · Data messages, which are handled by the client app.

    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

    Notification messages contain a predefined set of user-visible keys. Data messages, by contrast, contain only your user-defined custom key-value pairs.

    See the docs here https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search