Describe the bug
When running the application on start the following error is printed to console:
E/FirebaseMessagingPlugin( 6358): There was an exception when getting callback handle from Dart side
W/System.err( 6358): java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
W/System.err( 6358): at io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin.onMethodCall(FirebaseMessagingPlugin.java:126)
W/System.err( 6358): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:222)
W/System.err( 6358): at io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart(DartMessenger.java:96)
W/System.err( 6358): at io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage(FlutterJNI.java:656)
W/System.err( 6358): at android.os.MessageQueue.nativePollOnce(Native Method)
W/System.err( 6358): at android.os.MessageQueue.next(MessageQueue.java:326)
W/System.err( 6358): at android.os.Looper.loop(Looper.java:160)
W/System.err( 6358): at android.app.ActivityThread.main(ActivityThread.java:6669)
W/System.err( 6358): at java.lang.reflect.Method.invoke(Native Method)
W/System.err( 6358): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
W/System.err( 6358): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Tracing to the source it appears to be this line (126) in FirebaseMessagingPlugin.java:
try {
Map<String, Long> callbacks = ((Map<String, Long>) call.arguments);
setupCallbackHandle = callbacks.get("setupHandle");
backgroundMessageHandle = callbacks.get("backgroundHandle");
} catch (Exception e) {
Log.e(TAG, "There was an exception when getting callback handle from Dart side");
e.printStackTrace();
}
Possibly related? (I don't know, I'm really not a in my element here in Java...)
To Reproduce
Steps to reproduce the behavior:
home.dart (included in full just in case)
import "package:cloud_firestore/cloud_firestore.dart";
import "package:firebase_messaging/firebase_messaging.dart";
import "package:flutter/material.dart";
import "package:flutter_hybrid_alert/src/api/firestore.dart";
import "package:flutter_hybrid_alert/src/api/handlers.dart";
import "package:flutter_hybrid_alert/src/api/storage.dart";
import "package:flutter_hybrid_alert/src/models/models.dart";
import "package:flutter_hybrid_alert/src/routes.dart";
import "package:flutter_hybrid_alert/src/store/actions/user_actions.dart";
import "package:flutter_hybrid_alert/src/store/app_state.dart";
import "package:flutter_hybrid_alert/src/store/reducers/auth_reducer.dart";
import "package:flutter_hybrid_alert/src/ui/login.dart";
import "package:flutter_hybrid_alert/src/widgets/indicators/app_loading.dart";
import "package:flutter_local_notifications/flutter_local_notifications.dart";
import "package:flutter_redux/flutter_redux.dart";
import "package:nested_navigators/nested_nav_item.dart";
import "package:nested_navigators/nested_navigators.dart";
import "package:redux/redux.dart";
enum NestedNavItemKey { blacklist, recent, history, settings }
/// showNotification - Init local notifications and show a new one.
void showNotification(String body) {
final androidInitSettings = AndroidInitializationSettings("@mipmap/ic_launcher");
final initSettings = InitializationSettings(androidInitSettings, null);
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
flutterLocalNotificationsPlugin.initialize(initSettings);
const String notificationChannel = "HybridAlert";
final androidPlatformChannelSpecifics = AndroidNotificationDetails(
notificationChannel,
notificationChannel,
"Alerts for Hybrid platform.",
importance: Importance.Max,
priority: Priority.High,
ticker: "ticker",
);
final platformChannelSpecifics = NotificationDetails(androidPlatformChannelSpecifics, null);
flutterLocalNotificationsPlugin.show(0, notificationChannel, body, platformChannelSpecifics);
}
Future<dynamic> handleBackgroundNotifications(Map<String, dynamic> message) {
if (message.containsKey("data")) {
// Handle data message
final dynamic data = message["data"];
showNotification(data["name"]);
}
}
/// handleNotifications - Force local notifications.
Future<dynamic> handleNotifications(Map<String, dynamic> message) async {
showNotification(message["data"]["name"]);
}
class Home extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _HomeState();
}
}
class _HomeState extends State<Home> {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
AppUserSettings settings;
String userId;
Store store;
@override
void initState() {
super.initState();
// FCM Setup
_firebaseMessaging.requestNotificationPermissions();
_firebaseMessaging.getToken().then(handleSetUserToken);
_firebaseMessaging.configure(
onMessage: handleNotifications,
onBackgroundMessage: handleBackgroundNotifications,
);
if (userId == null) {
getStorageUser().then((String id) {
store.dispatch(SetUserFBEmailAction(id));
setState(() {
userId = id;
});
});
}
}
@override
Widget build(BuildContext context) {
store = StoreProvider.of<AppState>(context);
final AppState state = store.state;
final Stream<DocumentSnapshot> userStream =
userId != null ? usersRef.document(userId).get().asStream() : null;
return StreamBuilder(
stream: userStream,
builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (!snapshot.hasData || state.loading.settings) {
return buildAppLoadingIndicator("Loading settings...");
}
/* Initialize User Store Data
======================================== */
// Set hybrid email in store from firebase
final AppUser appUser = AppUser.fromJson(snapshot.data.data);
final String hybridEmail = appUser.email;
final String stateHybridEmail = state.user.hybridEmail;
final bool hybridEmailChanged = hybridEmail != stateHybridEmail;
if (hybridEmailChanged) {
store.dispatch(SetUserHybridEmailAction(hybridEmail));
}
// Set firebase userId as fbEmail.
if (state.user.fbEmail == null) {
store.dispatch(SetUserFBEmailAction(userId));
}
// Build the Settings UI.
return NestedNavigators(
items: {
NestedNavItemKey.recent: NestedNavigatorItem(
initialRoute: Routes.recent,
icon: Icons.home,
text: "Recent",
),
NestedNavItemKey.history: NestedNavigatorItem(
initialRoute: Routes.history,
icon: Icons.history,
text: "History",
),
NestedNavItemKey.blacklist: NestedNavigatorItem(
initialRoute: Routes.blacklist,
icon: Icons.list,
text: "Blacklist",
),
NestedNavItemKey.settings: NestedNavigatorItem(
initialRoute: Routes.settings,
icon: Icons.settings,
text: "Settings",
),
},
generateRoute: (routeSettings) {
return Routes.generateRoute(routeSettings, store.state);
},
buildBottomNavigationItem: (key, item, selected) => BottomNavigationBarItem(
icon: Icon(
item.icon,
// color: Colors.blue,
),
title: Text(
item.text,
style: TextStyle(
fontSize: 18,
),
),
),
bottomNavigationBarTheme: Theme.of(context).copyWith(
splashColor: Colors.grey,
),
);
},
);
}
}
class AppHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StoreConnector<AppState, AppState>(
converter: (store) {
return store.state;
},
builder: (BuildContext context, AppState state) {
final AuthState authState = state.auth;
final bool firebaseAuth = authState.firebaseAuthenticated;
final bool hybridAuth = authState.hybridAuthenticated;
final bool isLoggedIn = hybridAuth && firebaseAuth;
if (isLoggedIn) {
return Home();
}
return LoginScreen();
},
);
}
}
Expected behavior
Should not throw an error on initialization.
Additional context
I'm really not sure what I can do to get this to not throw an error.
I have successfully suppressed the error by naming my background handler literally the same as what is being called in the library code... which seems a little ridiculous given that the documentation named the handler something totally different.
source
try {
Map<String, Long> callbacks = ((Map<String, Long>) call.arguments);
setupCallbackHandle = callbacks.get("setupHandle");
// THIS RIGHT HERE "backgroundHandle" HAS TO BE THE NAME??
backgroundMessageHandle = callbacks.get("backgroundHandle");
} catch (Exception e) {
Log.e(TAG, "There was an exception when getting callback handle from Dart side");
e.printStackTrace();
}
I have successfully suppressed the error by naming my background handler literally the same as what is being called in the library code... which seems a little ridiculous given that the documentation named the handler something totally different.
source
try { Map<String, Long> callbacks = ((Map<String, Long>) call.arguments); setupCallbackHandle = callbacks.get("setupHandle"); // THIS RIGHT HERE "backgroundHandle" HAS TO BE THE NAME?? backgroundMessageHandle = callbacks.get("backgroundHandle"); } catch (Exception e) { Log.e(TAG, "There was an exception when getting callback handle from Dart side"); e.printStackTrace(); }
This solved to me, thanks.
Hi @DannyHinshaw
given your last message I feel safe to close this issue,
if you disagree please write in the comments
and I will reopen it.
Thank you
Most helpful comment
I have successfully suppressed the error by naming my background handler literally the same as what is being called in the library code... which seems a little ridiculous given that the documentation named the handler something totally different.
source