1

i am using local notifications. I want to show a notification in onMessage with local Notification but i keep getting this error:Failed to handle method call . after googling the answer keep referring to app icon.

after changing the app icon to the name in my drawer still yet i keep getting the error.

I have tried @mipmap/ic_launcher and mipmap/ic_launcher both of them. app_icon is the name of the playstore-icon.png that I named

the drawer image

the andriodManifest.xml

here is my code

class MyProfile extends StatefulWidget {
  @override
  _MyProfileState createState() => _MyProfileState();
}

class _MyProfileState extends State<MyProfile> {
  Map dataset;
  bool state = false;
  String selected = "first";

  FirebaseMessaging messaging = FirebaseMessaging.instance;

  final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();

  AndroidNotificationChannel channel = AndroidNotificationChannel(
    'faithmeetslove', // id
    'High Importance Notifications', // title
    'This channel is used for important notifications.', // description
    importance: Importance.max,
  );

  Future<void> saveTokenToDatabase(String token) async {
    String userId = auth.currentUser.uid;
    await firestore.collection("users").doc(userId).update({
      'tokens': token,
    });
  }

  @override
  void initState() {
    super.initState();
    final InitializationSettings initializationSettings =
        InitializationSettings(
            android: AndroidInitializationSettings("playstore-icon.png"),
            iOS: IOSInitializationSettings(
              requestAlertPermission: false,
              requestBadgePermission: false,
              requestSoundPermission: false,
            ));
    getData();
    getTokens();
    getUserLocation();
  }

  getTokens() async {
    String token = await FirebaseMessaging.instance.getToken();
    await saveTokenToDatabase(token);
    FirebaseMessaging.instance.onTokenRefresh.listen(saveTokenToDatabase);
    if (Platform.isIOS) {
      FirebaseMessaging.instance.requestPermission();
    }
    NotificationSettings settings = await messaging.requestPermission(
      alert: true,
      announcement: false,
      badge: true,
      carPlay: false,
      criticalAlert: false,
      provisional: false,
      sound: true,
    );

    FirebaseMessaging.instance
        .getInitialMessage()
        .then((RemoteMessage message) {
      if (message != null) {
        Navigator.pushNamed(context, message.data['view']);
      }
    });
    print('User granted permission: ${settings.authorizationStatus}');
    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      print('Message data: ${message.data['key']}');

      //message.data
      if (message.notification != null) {
        print('Message also contained a notification: ${message.notification}');
      }
      RemoteNotification notification = message.notification;
      AndroidNotification android = message.notification?.android;

      // If `onMessage` is triggered with a notification, construct our own
      // local notification to show to users using the created channel.

      if (notification != null && android != null) {
        flutterLocalNotificationsPlugin.show(
            notification.hashCode,
            notification.title,
            notification.body,
            NotificationDetails(
              android: AndroidNotificationDetails(
                channel.id,
                channel.name,
                channel.description,
                icon: android?.smallIcon,
                // other properties...
              ),
            ));
      }
    });
    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      debugPrint('A new onMessageOpenedApp event was published!');
      // _navigator.currentState.pushNamed('/' + message.data['view']);
    });
  }

  getData() async {
    setState(() {
      state = true;
    });
    final datastore =
        await firestore.collection('users').doc(auth.currentUser.uid).get();
    if (mounted) {
      setState(() {
        setState(() {
          dataset = datastore.data();
          state = false;
        });
      });
    }
  }
Gbenga B Ayannuga
  • 2,407
  • 3
  • 17
  • 38

1 Answers1

1

I think you are missing some initialisation steps, for example I did not see where you call initalize on FlutterLocalNotificationsPlugin. I write here the way I did it with remote and local messaging combined, I hope it helps.

First, make sure that you have these lines added to AndroidManifest.xml with your desired icon:

<meta-data
  android:name="com.google.firebase.messaging.default_notification_icon"
  android:resource="@drawable/ic_notification"/>
<meta-data
  android:name="com.google.firebase.messaging.default_notification_channel_id"
  android:value="mychannel" /> 

Then complete initialisation steps, something like this, I call it from initState:

void initNotifications() async {
  FirebaseMessaging messaging = FirebaseMessaging.instance;

  NotificationSettings notificationSettings =
      await messaging.requestPermission(
    alert: true,
    announcement: false,
    badge: true,
    carPlay: false,
    criticalAlert: false,
    provisional: false,
    sound: true,
  );

  if (notificationSettings.authorizationStatus ==
      AuthorizationStatus.authorized) {
    await FirebaseMessaging.instance
        .setForegroundNotificationPresentationOptions(
      alert: true,
      badge: true,
      sound: true,
    );

    const AndroidNotificationChannel channel = AndroidNotificationChannel(
      'mychannel', 
      'title',
      'description',
      importance: Importance.max,
    );

    final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
        FlutterLocalNotificationsPlugin();

    flutterLocalNotificationsPlugin.initialize(
        InitializationSettings(
            android:
                AndroidInitializationSettings('@drawable/ic_notification'),
            iOS: IOSInitializationSettings()),
        onSelectNotification: _onSelectNotification);

    await flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(channel);

    FirebaseMessaging.onMessage.listen((RemoteMessage message) {
      if (message.notification == null) {
        return;
      }

      RemoteNotification notification = message.notification!;

      if (notification.android != null) {
        flutterLocalNotificationsPlugin.show(
            notification.hashCode,
            notification.title,
            notification.body,
            NotificationDetails(
                android: AndroidNotificationDetails(
              channel.id,
              channel.name,
              channel.description,
            )));
      }
    });


    FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
      // do something with message
    });

    messaging.getInitialMessage().then((RemoteMessage? message) {

      if (message == null) {
        return;
      }

      // do something with message

    });
  }
}

In the above code _onSelectNotification is a function that will run when user pushes a notification while the app is active, I think only on Android. This function looks like:

Future _onSelectNotification(String? payload) {
   // do something with payload
}
Peter Koltai
  • 8,296
  • 2
  • 10
  • 20
  • 1
    @drawable/ic_notification' i am confused here. i should add my icon to the drawable folder? because the icons is in the res folder – Gbenga B Ayannuga Aug 15 '21 at 10:45
  • please check the image in the question? my icon is playstore-icon.png – Gbenga B Ayannuga Aug 15 '21 at 10:46
  • i am getting error: FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:processDebugResources'. > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade > Android resource linking failed /Users/mac/Documents/FaithMeetsLove-App-main/build/app/intermediates/packaged_manifests/debug/AndroidManifest.xml:69: AAPT: error: resource drawable/playstore-icon (aka com.FaithMeetsLove.FaithMeetsLove:drawable/playstore-icon) not found. – Gbenga B Ayannuga Aug 15 '21 at 10:48
  • You need icons in different sizes, and put them into the `drawable-hdpi` etc. folders, so that Android will find it. See the accepted answer [here](https://stackoverflow.com/questions/64304512/flutter-firebase-push-notification-icon), and check out this [icon generator](http://romannurik.github.io/AndroidAssetStudio/icons-notification.html#source.type=image&source.space.trim=0&source.space.pad=0&name=ic_notification). – Peter Koltai Aug 15 '21 at 10:52
  • yes... Thanks.. Can you help me out with andriod and ios Push notification payload.. – Gbenga B Ayannuga Aug 15 '21 at 17:41
  • Good to hear, you are welcome. What's your problem with payload? – Peter Koltai Aug 15 '21 at 17:44
  • with the channel... i want to push with the channel – Gbenga B Ayannuga Aug 15 '21 at 17:44
  • i am sending using node.js fcm back end so i want to send using payload... with the channel – Gbenga B Ayannuga Aug 15 '21 at 17:45
  • Sorry, I don't understand this. Maybe you can post another question and paste link here, comments are not really useful for extended discussions. – Peter Koltai Aug 15 '21 at 17:46
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/236031/discussion-between-peter-koltai-and-gbenga-b-ayannuga). – Peter Koltai Aug 15 '21 at 17:49
  • https://stackoverflow.com/questions/68794078/how-to-add-channel-id-to-push-notification-payload – Gbenga B Ayannuga Aug 15 '21 at 17:54