Reputation: 2792
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
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;
});
});
}
}
Upvotes: 1
Views: 1790
Reputation: 9744
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
}
Upvotes: 1