MaikuB / flutter_local_notifications

A Flutter plugin for displaying local notifications on Android, iOS, macOS and Linux
2.47k stars 1.4k forks source link

Cast error when app is in background and MessagingStyleInformation #2299

Closed mbenci closed 6 months ago

mbenci commented 7 months ago

Describe the bug When I try to show a notification with style MessagingStyleInformation with app in background I get error "java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long"

To Reproduce In my project the application listens to push notifications sent via FCM and shows local notifications with MessagingStyleInformation style. When the app is in the foreground the notification is shown correctly. When the app is in the background the show method has an error. No problem if I use other styles for the message, for example InboxStyleInformation or BigTextStyleInformation.

In my case: Plugin version: 17.0.0 Flutter version: 3.19.4

[  +64 ms] E/MethodChannel#dexterous.com/flutter/local_notifications(24988): Failed to handle method call
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988): java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at com.dexterous.flutterlocalnotifications.models.NotificationDetails.readMessages(NotificationDetails.java:461)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at com.dexterous.flutterlocalnotifications.models.NotificationDetails.readMessagingStyleInformation(NotificationDetails.java:427)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at com.dexterous.flutterlocalnotifications.models.NotificationDetails.readStyleInformation(NotificationDetails.java:412)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at com.dexterous.flutterlocalnotifications.models.NotificationDetails.readPlatformSpecifics(NotificationDetails.java:253)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at com.dexterous.flutterlocalnotifications.models.NotificationDetails.from(NotificationDetails.java:238)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.extractNotificationDetails(FlutterLocalNotificationsPlugin.java:1643)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.show(FlutterLocalNotificationsPlugin.java:1586)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.onMethodCall(FlutterLocalNotificationsPlugin.java:1413)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:267)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:292)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:319)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at android.os.Handler.handleCallback(Handler.java:942)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at android.os.Handler.dispatchMessage(Handler.java:99)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at android.os.Looper.loopOnce(Looper.java:240)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at android.os.Looper.loop(Looper.java:351)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at android.app.ActivityThread.main(ActivityThread.java:8377)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at java.lang.reflect.Method.invoke(Native Method)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
[        ] E/MethodChannel#dexterous.com/flutter/local_notifications(24988):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
[  +26 ms] I/flutter (24988): FlutterFire Messaging: An error occurred in your background messaging handler:
[        ] I/flutter (24988): PlatformException(error, java.lang.Integer cannot be cast to java.lang.Long, null, java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
[        ] I/flutter (24988):   at com.dexterous.flutterlocalnotifications.models.NotificationDetails.readMessages(NotificationDetails.java:461)
[        ] I/flutter (24988):   at com.dexterous.flutterlocalnotifications.models.NotificationDetails.readMessagingStyleInformation(NotificationDetails.java:427)
[        ] I/flutter (24988):   at com.dexterous.flutterlocalnotifications.models.NotificationDetails.readStyleInformation(NotificationDetails.java:412)
[        ] I/flutter (24988):   at com.dexterous.flutterlocalnotifications.models.NotificationDetails.readPlatformSpecifics(NotificationDetails.java:253)
[        ] I/flutter (24988):   at com.dexterous.flutterlocalnotifications.models.NotificationDetails.from(NotificationDetails.java:238)
[        ] I/flutter (24988):   at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.extractNotificationDetails(FlutterLocalNotificationsPlugin.java:1643)
[        ] I/flutter (24988):   at com.dexterous.flutterlocalnotifications.FlutterLocalNotificationsPlugin.show(FlutterLocalNotificationsPlugin.java

Sample code to reproduce the problem

List<Message> messages = [];

  Person person =
      Person(name: notificationTitle, key: jsonDecode(payload)['authorId']);

  messages.add(
    Message(
      notificationBody,
      DateTime.fromMillisecondsSinceEpoch(jsonDecode(payload)['timestamp']),
      person,
    ),
  );

  activeNotificationsFromFile[chatId] = messages
      .map((message) => _fromMessageToActiveNotification(message))
      .toList();

  await _updateActiveNotificationFile(activeNotificationsFromFile);

  final MessagingStyleInformation messagingStyle = MessagingStyleInformation(
      person,
      groupConversation: true,
      conversationTitle: chatName,
      htmlFormatContent: true,
      htmlFormatTitle: true,
      messages: messages);

  final AndroidNotificationDetails androidNotificationDetails =
      AndroidNotificationDetails(
    chatId,
    chatName,
    category: AndroidNotificationCategory.message,
    styleInformation: messagingStyle,
    importance: Importance.max,
    priority: Priority.high,
  );

  final NotificationDetails notificationDetails =
      NotificationDetails(android: androidNotificationDetails);

  await _flutterLocalNotificationsPlugin.show(chatId.hashCode,
      notificationTitle, notificationBody, notificationDetails);
Rongix commented 6 months ago

@mbenci I've got the same problem and the fix is quite easy. I'm not an Android developer so it may not be an idiomatic solution but the problem lies in: flutter_local_notifications/android/src/main/java/com/dexterous/flutterlocalnotifications/models/NotificationDetails.java L461

change

                (Long) messageData.get(TIMESTAMP)

to

                (Long) ((Integer) messageData.get(TIMESTAMP)).longValue(),
MaikuB commented 6 months ago

This has been addressed with a release published. You might be aware of this but the reason this is happening is due to date/time values being used that are way further in the past within the range of epoch time (i.e. 1st of January 1970) as per API docs, the timestamp is converted to milliseconds since epoch. Thought I would mention in case neither of you are aware or in case you have erroneous values for the timestamp as realistically an app wouldn't have such date/time values