Ad

Error: Failed To Handle Method Call On Local Notification

- 1 answer

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;
        });
      });
    }
  }
Ad

Answer

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
}
Ad
source: stackoverflow.com
Ad