I want to show notification based on a condition. I tried with flutter local notification package but I was only getting the foreground and background notification. if I close the app i was not having any notification from app.
example:
app is fetching the data from real-time-database firebase and data base is getting the frequency value from hardware, if frequency is greater than 50 then show notification.
if there is any another way to implement, you can also suggest me that
part of the code:
NotificationService notificationsServices = NotificationService();
void initState(){
super.initState();
notificationsServices.intializeNotification();
}
if(_displayTemp>135 || _displayVib>135)
{
notificationsServices.sendN("Alert", _displayMsg);
}
class NotificationService {
final FlutterLocalNotificationsPlugin flutterNotificationsPlugin = FlutterLocalNotificationsPlugin();
final AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('shield');
void intializeNotification() async {
InitializationSettings initializationSettings= InitializationSettings(
android: initializationSettingsAndroid
);
await flutterNotificationsPlugin.initialize(initializationSettings);
}
void sendN(String title,String body) async {
AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails(
'channelId 2',
'channelName',
importance: Importance.max,
priority: Priority.high,
playSound: true,
//ongoing: true
);
NotificationDetails notificationDetails = NotificationDetails(
android: androidNotificationDetails,
);
await flutterNotificationsPlugin.show(
0,
title,
body,
notificationDetails
);
}
}
Related
I'm trying to setup my mobile app, so that when a user gets a FCM message, when they click on it, I can use data within the message to route them to appropriate screen.
My FCM message looks like this:
const fcmMessage = {
notification: {
title: title,
body: message
},
data:{
type:'Chat',
Name: 'Mike',
body:'test'
},
android: {
notification: {
title:title,
body: message,
channel_id:'high_importance_channel'
}
},
token: msgToken,
};
then within my main() method, I am initializing the Flutter_Local_notifications as per the code snippet below.
The issue is when I click on the notification, the payload is always an empty string?
These are the code lines that perform this. Why is the NotificationResponse.payload empty string?
ultimately, I need access the "data" object in the FCM message.
void onDidReceiveNotificationResponse(NotificationResponse notificationResponse) async {
print(notificationResponse.payload);
}
Here is the full main() method.
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Set the background messaging handler early on, as a named top-level function
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
if (!kIsWeb) {
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title/
importance: Importance.high,
);
}
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
var initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/ic_launcher');
var initializationSettingsIOs = DarwinInitializationSettings();
var initSettings = InitializationSettings(
android: initializationSettingsAndroid, iOS: initializationSettingsIOs);
void onDidReceiveNotificationResponse(NotificationResponse notificationResponse) async {
print(notificationResponse.payload);
}
await flutterLocalNotificationsPlugin.initialize(initSettings,onDidReceiveNotificationResponse: onDidReceiveNotificationResponse,);
/// Create an Android Notification Channel.
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Got a message whilst in the foreground!');
print('Message data: ${message.data}');
if (message.notification != null) {
RemoteNotification? notification = message.notification;
AndroidNotification? android = message.notification?.android;
FlutterLocalNotificationsPlugin s = FlutterLocalNotificationsPlugin();
s.show(
notification.hashCode,
notification?.title,
notification?.body,
NotificationDetails(
android: AndroidNotificationDetails(channel.id, channel.name,
icon: 'launch_background',
channelDescription: channel.description,
importance: Importance.max,
priority: Priority.high,
ongoing: true,
styleInformation: BigTextStyleInformation('')),
),
);
}
});
runApp(MyApp());
}
UPDATE, found what I needed. In the LocalNotification show method, we can add the payload attribute and set it to whatever part of the message.
For my use case, I encode the message.data , and then in the didReceive method, I can decode back to JSON object and use as needed.
s.show(
payload: jsonEncode(message.data),
notification.hashCode,
notification?.title,
notification?.body,
NotificationDetails(
android: AndroidNotificationDetails(channel.id, channel.name,
icon: 'launch_background',
channelDescription: channel.description,
importance: Importance.max,
priority: Priority.high,
ongoing: true,
styleInformation: BigTextStyleInformation('')),
),
);
Here is my code below :
const AndroidNotificationChannel notificationChannel = AndroidNotificationChannel(
'high_importance_channel',
'high importance Notificaion',
'this channel is used for import notification',
importance: Importance.high,
playSound: true,
);
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
Future<void> firebaseBackgroundMessageHandler(RemoteMessage message) async {
await firebaseMessageHandler(message);
}
Future<void> firebaseForegroundMessageHandler(RemoteMessage message) async {
await firebaseMessageHandler(message);
}
Future<void> firebaseMessageHandler(RemoteMessage message) async {
await Firebase.initializeApp();
try {
flutterLocalNotificationsPlugin.show(
message.notification.hashCode,
message.data["title"].toString(),
message.data["body"].toString(),
NotificationDetails(
android: AndroidNotificationDetails(notificationChannel.id, notificationChannel.name, notificationChannel.description),
));
} catch (_err) {}
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(firebaseBackgroundMessageHandler);
FirebaseMessaging.onMessage.listen(firebaseForegroundMessageHandler);
//FirebaseMessaging.onMessageOpenedApp.listen(firebaseMessageHandler);
final AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('e_app');
final InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>()?.createNotificationChannel(notificationChannel);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(alert: true, badge: true, sound: true);
}
The code is working fine for a single notification but whenever I send multiple notifications to android, it shows only the last notification in the status bar.
Could anyone help me about
how to show multiple notifications in the status bar using the flutter local notification plugin?
If you want to group your notifications, there is an option to do that in flutter_local_notifications.
To do this, you can add the following in your code
for ios : threadIdentifier in IOSNotificationDetails
for android : groupChannelId, groupChannelName, groupChannelDescription,
You can find these in the docs here: https://pub.dev/packages/flutter_local_notifications#displaying-a-notification under 'Grouping notifications'.
Basically notifications under same threadId or groupId will all be grouped and shown
I am using local_notifications plugin in my android flutter app. I do everything according to the documentation and the notifications work but without sound and pop-up windows. Importance and priority set to max. Maybe the reason is in some settings of my phone or its OS (MIUI Global 11.0.3, Android 9 PKQ1)?
Notification code:
FlutterLocalNotificationsPlugin notificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<void> initNotificationPlugin() async {
const AndroidInitializationSettings androidSettings =
AndroidInitializationSettings('ic_launcher');
final IOSInitializationSettings iosSettings =
IOSInitializationSettings();
final initSettings =
InitializationSettings(android: androidSettings, iOS:
iosSettings);
await notificationsPlugin.initialize(initSettings);
}
void showNotification(String title, String body,
DateTime dateTime, int id) async {
var androidDetails = AndroidNotificationDetails(
'notificationChannel', 'channel', 'description',
importance: Importance.max,
priority: Priority.max,
playSound: true,
showWhen: false,
enableVibration: true);
var iosDetails = IOSNotificationDetails();
var details = NotificationDetails(android: androidDetails, iOS:
iosDetails);
await notificationsPlugin.zonedSchedule(
id,
title,
body,
timezone.TZDateTime.from(
dateTime, timezone.getLocation('Europe/Moscow')),
details,
androidAllowWhileIdle: true,
uiLocalNotificationDateInterpretation:
UILocalNotificationDateInterpretation.absoluteTime);
}
I'm using flutterlocalnotifications package and FCM to send notifications to my users. Everything working perfectly. I can show notifications to my users when my app is in the background, foreground, or closed. I can reach payload value in foreground and background, but when the app is killed I can't reach payload anymore. I test in catlog but there isn't any print in the onSelectNotification.
How can reach this payload?
This is my notification handler class
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.high,
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// await Firebase.initializeApp();
//Bildirim geldiği anda datayı elde ettiğimiz alan
final dynamic data = message.data;
print('Data in background : ${data.toString()}');
NotificationHandler.showNotification(data);
}
class NotificationHandler {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
static final NotificationHandler _singleton = NotificationHandler._internal();
factory NotificationHandler() {
return _singleton;
}
NotificationHandler._internal();
BuildContext myContext;
initializeFCMNotifications(BuildContext context) async {
await _firebaseMessaging.setForegroundNotificationPresentationOptions(
alert: true, badge: true, sound: true);
var initializationSettingsAndroid =
AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = IOSInitializationSettings(
onDidReceiveLocalNotification: onDidReceiveLocalNotification);
var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
await _firebaseMessaging.subscribeToTopic("all");
await FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage message) {
if (message != null) {
print('initialmessage tetiklendi : ' + message.data.toString());
}
});
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
var notification = message.notification;
var android = message.notification?.android;
print('ONMESSAGE ÇALIŞTI');
print('onmessage tetiklendi data : ' +
message.data['message'] +
' title ' +
message.data['title']);
showNotification(message.data);
});
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('Onmessageopened : ' + message.data.toString());
});
}
static void showNotification(Map<String, dynamic> data) async {
const androidPlatformChannelSpecifics = AndroidNotificationDetails(
'1234', 'Yeni Mesaj', 'your channel description',
importance: Importance.max, priority: Priority.high, ticker: 'ticker');
const IOSPlatformChannelSpecifics = IOSNotificationDetails();
const platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: IOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0, data['title'], data['message'], platformChannelSpecifics,
payload: 'The value when notification tapped');
}
Future onSelectNotification(String payload) async {
if (payload != null) {
debugPrint('notification payload : $payload');
}
}
Future onDidReceiveLocalNotification(
int id, String title, String body, String payload) {}
}
and these are the versions of the packages I use
firebase_messaging: ^9.1.1
flutter_local_notifications: ^5.0.0+1
I am trying to navigate to a specific page using local notification, the moment the user touches the notification, below I leave the code of how I am doing it, basically, the problem is when onSelectNotification is called everything that is before is executed but Once Navigator.push is called, it does not go to the screen that I tell it and it does not raise any exceptions and what is after is not executed either.
/// Allows you to navigate to a specific screen from the notification
Future onSelectNotification(String payload) async {
if (payload != null) {
debugPrint('Notification payload: $payload');//it shows
}
await Navigator.push(context, MaterialPageRoute(builder: (context) => AnyScreen()));
debugPrint("go to AnyScreen");//does not show it
}
#override
void initState() {
// TODO: implement initState
super.initState();
/// local notication inicialization
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
'This channel is used for important notifications.', // description
importance: Importance.max,
);
FlutterLocalNotificationsPlugin flip =
new FlutterLocalNotificationsPlugin();
flip
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
const AndroidInitializationSettings android =
AndroidInitializationSettings('app_icon');
final IOSInitializationSettings iOS = IOSInitializationSettings();
final MacOSInitializationSettings macOS = MacOSInitializationSettings();
final InitializationSettings initializationSettings =
InitializationSettings(android: android, iOS: iOS, macOS: macOS);
flip.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
/// listen when the app is open
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
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) {
flip.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id, channel.name, channel.description,
icon: android?.smallIcon,
// other properties...
priority: Priority.high),
));
}
});
}
...