do an action after click on notification flutter? - flutter

hello am trying to navigate to a second screen after clicking on notification using flutter_local_notifications
https://pub.dev/packages/flutter_local_notifications
final BehaviorSubject<String?> selectNotificationSubject =
BehaviorSubject<String?>();
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
void initializeNotifcations() async {
var initialzationSettings =
InitializationSettings(android: initializationSettingsAndroid);
await flutterLocalNotificationsPlugin.initialize(initialzationSettings,
onDidReceiveBackgroundNotificationResponse:
(NotificationResponse notificationResponse) {
selectNotificationSubject.add(notificationResponse.payload);
});
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()!
.requestPermission();
}
void configureDidReceiveLocalNotificationSubject() {
print('test01');
selectNotificationSubject.stream.listen((String? payload) async {
print('test02');
});
}
not listining to the stream if you got an example of how to make it with the best practice it will help

flutterLocalNotificationsPlugin
.getNotificationAppLaunchDetails()
.then((value) {
.then((value) async {
if (value.didNotificationLaunchApp) {
if (value.payload != null) {
// do something
}

void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await initNotification();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler;
...
}
Future initNotification() async {
var initializationSettingsAndroid =
new AndroidInitializationSettings("#drawable/kin_removebg");
var initializationSettingsIOS = new IOSInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false,
onDidReceiveLocalNotification:
(int? id, String? title, String? body, String? payload) async {});
var initializationSettings = new InitializationSettings(
android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
final NotificationAppLaunchDetails? notificationAppLaunchDetails =
await flutterLocalNotificationsPlugin.getNotificationAppLaunchDetails();
final didNotificationLaunchApp =
notificationAppLaunchDetails?.didNotificationLaunchApp ?? false;
if (didNotificationLaunchApp) {
var payload = notificationAppLaunchDetails!.payload;
onSelectNotification(payload);
} else {
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onDidReceiveNotificationResponse:onSelectNotification,
onDidReceiveBackgroundNotificationResponse: onSelectNotification,
}
}
onSelectNotification(NotificationResponse notificationResponse) async {
var payloadData = jsonDecode(notificationResponse.payload);
print("payload $payload");
if(payloadData["type"]=="something" && payloadData["id"]!="something"){
Navigator.of(navigatorKey.currentContext!).push(
MaterialPageRoute(
builder: (context) =>
SomethingScreen(id: payloadData["id"],)));
}
}

Related

The argument type 'Future<dynamic> Function(String)' can't be assigned to the parameter type 'void Function(String?)?'

I am using flutter local notification but it doesn't work and it suddenly makes my app shuts down. Here's my code.
initializeNotifications() async {
var initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/launcher_icon');
var initializationSettingsIOS = IOSInitializationSettings();
var initializationSettings = InitializationSettings(
android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
var flutterLocalNotificationsPlugin;
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
}
Future onSelectNotification(String payload) async {
if (payload != null) {
debugPrint('notification payload: ' + payload);
}
await Navigator.push(
context,
new MaterialPageRoute(builder: (context) => MedicineReminder()),
);
}
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onSelectNotification: (payload) {
if (payload != null) {
onSelectNotification(payload!);
}
}
);

How can I use a parameter from sharedPreferences in workmanager in Flutter?

I am trying to send a notification based on parameter saved the user saves on sharedPreferences and is added to the url to make the call. The notification is working if I write the savedCity but when I try to get from sharedPreferences it fails. How can I make this work?
void callbackDispatcher() {
Workmanager.executeTask((task, inputData) async {
String savedCity = "";
// final prefs = await SharedPreferences.getInstance();
// savedCity = prefs.getString('defaultCity') ?? "";
if (task == 'uniqueKey') {
var response = await http.get(Uri.parse('http://api.openweathermap.org/data/2.5/weather?q=$savedCity&units=metric&appid=$API_KEY'));
Weather dataComingFromTheServer = Weather.fromJson(json.decode(response.body));
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails('your channel id', 'your channel name',
'your channel description',
importance: Importance.max,
priority: Priority.high,
showWhen: false);
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0,
dataComingFromTheServer.name,
'${dataComingFromTheServer.weather[0].description} ${dataComingFromTheServer.main.tempMin}ºC - ${dataComingFromTheServer.main.tempMax}ºC',
platformChannelSpecifics,
payload: 'item x');
}
return Future.value(true);
});
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings(
'#mipmap/ic_launcher');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings();
final MacOSInitializationSettings initializationSettingsMacOS =
MacOSInitializationSettings();
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: initializationSettingsMacOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
Workmanager.initialize(
callbackDispatcher,
isInDebugMode:
true);
Workmanager.registerPeriodicTask(
"1",
"uniqueKey",
frequency: Duration(minutes: 15),
);
runApp(MyApp());
}
void setPreference(String cityName) async {
final prefs = await SharedPreferences.getInstance();
prefs.setString('defaultCity', cityName);
}

how to open a certain page using local notification in Flutter? (Not FCM)

no, I am not asking about Firebase Cloud Messaging notification here, but purely using local notification package from here flutter local notification
I want if my user click the notification then it will be directed to a certain page. how to do that ?
currently my code is like this
class LocalNotificationService {
late FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin;
LocalNotificationService._privateConstructor() {
_init();
}
static final LocalNotificationService _instance = LocalNotificationService._privateConstructor();
static LocalNotificationService get instance => _instance; // singleton access
void _init() {
_flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
_initializePlatformSpecifics();
}
Future<void> _initializePlatformSpecifics() async {
var androidInitializationSettings = AndroidInitializationSettings("app_notification_icon");
var iOSInitializationSettings = IOSInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
onDidReceiveLocalNotification: (id, title, body, payload) async {
// do something if notification is clicked
},
);
final initializationSettings = InitializationSettings(
android: androidInitializationSettings,
iOS: iOSInitializationSettings,
);
await _flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
void showSimpleNotification({
required String title,
required String body,
required NotificationType notificationType,
}) async {
var android = _setAndroidNotificationDetails(notificationType);
var ios = IOSNotificationDetails();
var notificationDetails = new NotificationDetails(android: android, iOS: ios);
await _flutterLocalNotificationsPlugin.show(
1, // only need to show one notification in the notification tray, so it is ok if we use the Notification ID
title,
body,
notificationDetails,
);
}
}
First thing you need to create a GlobalKey for navigation like the following:
GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
and inside MaterialApp, set the navigatorKey property to be our created key like the following property
navigatorKey: navigatorKey
Now you can use the navigation methods from inside the current state of key, example:
navigatorKey.currentState!.push()
i recommend reading plugin documentation
as per documentation
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('app_icon');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
onDidReceiveLocalNotification: onDidReceiveLocalNotification,
);
final MacOSInitializationSettings initializationSettingsMacOS =
MacOSInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false);
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: initializationSettingsMacOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
you can pass onSelectNotification function which will be called whenever user click on notification
from this function u can redirection to particular screen example as below
Future selectNotification(String payload) async {
if (payload != null) {
debugPrint('notification payload: $payload');
}
await Navigator.push(
context,
MaterialPageRoute<void>(builder: (context) =>
SecondScreen(payload)),);
}

The class 'FirebaseMessaging' doesn't have a default constructor Flutter 2

Before switching to Flutter 2, I was using an old version of firebaseMessaging without problems, and now I have the latest version.After upgrading I get the following error:
The class 'FirebaseMessaging' doesn't have a default constructor.
And:
The method 'configure' isn't defined for the type 'FirebaseMessaging'.
Full class:
class ShowNotifications {
static final FirebaseMessaging firebaseMessaging = FirebaseMessaging();
static FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
new FlutterLocalNotificationsPlugin();
static void initialization(){
var initializationSettingsAndroid =
new AndroidInitializationSettings('#mipmap/ic_launcher');
var initializationSettingsIOS = new IOSInitializationSettings();
var initializationSettings = new InitializationSettings(
android: initializationSettingsAndroid, iOS: initializationSettingsIOS);
flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
}
static void showNotification(String title, String body) async {
await _demoNotification(title, body);
}
static Future<void> _demoNotification(String title, String body) async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'channel_ID', 'channel name', 'channel description',
importance: Importance.max,
playSound: true,
// sound: 'sound',
// sound: true,
showProgress: true,
priority: Priority.high,
ticker: 'test ticker');
var iOSChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
android: androidPlatformChannelSpecifics, iOS: iOSChannelSpecifics);
await flutterLocalNotificationsPlugin
.show(0, title, body, platformChannelSpecifics, payload: 'test');
}
static Future onSelectNotification(String payload) async {
showDialog(
// context: context,
builder: (_) {
return new AlertDialog(
title: Text("PayLoad"),
content: Text("Payload : $payload"),
);
},
);
}
static notification(){
firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
showNotification(message['notification']['title'], message['notification']['body']);
// print("onMessage: $message");
},
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
}
}
I was able to control this class from all the application pages.
What do I need to change with the new version. So that I can use the class as it was in the past.
Try to update your firebase_messaging package and also take care to use compatile packages for the other Firebase SDKs. I would recommend to copy the ones from the official documentation for each one you use.
Here is a full example how the new Firebase Messaging SDK would work with the new API:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '../constants.dart';
FirebaseMessaging messaging = FirebaseMessaging.instance;
final _database = FirebaseDatabase.instance;
final _firestore = FirebaseFirestore.instance;
final _auth = FirebaseAuth.instance;
class MessagingService {
static bool showToast = true;
static String currentToken;
static void initialize() async {
await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (message.notification != null) {
print('Message also contained a notification: ${message.notification}');
}
if (showToast && message.notification != null) {
Fluttertoast.showToast(
msg: "${message.notification.title}: ${message.notification.body} ",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
//backgroundColor: Colors.red,
//textColor: Colors.white,
fontSize: 16.0,
);
}
});
messaging.onTokenRefresh.listen((String token) async {
await syncToken();
});
await syncToken();
}
static Future<String> getToken() async {
String token = await messaging.getToken();
return token;
}
static Future syncToken() async {
try {
String token = await messaging.getToken();
if (token != currentToken) {
if (syncDatabase == databases.RealtimeDatabase) {
await _database
.reference()
.child(
'$kNotificationTokensSyncBasePath${_auth.currentUser.uid}/$token')
.set(true);
} else {
await _firestore
.doc('$kNotificationTokensSyncBasePath${_auth.currentUser.uid}')
.set({'$token': true}, SetOptions(merge: true));
}
currentToken = token;
}
} catch (e) {
print(e);
}
return;
}
static Future unsyncToken(User user) async {
try {
String token = await messaging.getToken();
if (syncDatabase == databases.RealtimeDatabase) {
await _database
.reference()
.child('$kNotificationTokensSyncBasePath${user.uid}/$token')
.set(null);
} else {
await _firestore
.doc('$kNotificationTokensSyncBasePath${_auth.currentUser.uid}')
.set({'$token': FieldValue.delete()}, SetOptions(merge: true));
}
currentToken = null;
} catch (e) {
print(e);
}
return;
}
}

Flutter: Local Notification Scheduling

I am trying to set a scheduled alarm notification from the user selected date and time which i used showDatePicker for code below
DateTime _selectedDateAndTime;
Future _selectDayAndTimeL(BuildContext context) async {
DateTime _selectedDay = await showDatePicker(
context: context,
initialDate: DateTime.now(),
firstDate: DateTime(2021),
lastDate: DateTime(2030),
builder: (BuildContext context, Widget child) => child);
TimeOfDay _selectedTime = await showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
);
if (_selectedDay != null && _selectedTime != null) {
//a little check
}
setState(() {
_selectedDateAndTime = DateTime(
_selectedDay.year,
_selectedDay.month,
_selectedDay.day,
_selectedTime.hour,
_selectedTime.minute,
);
// _selectedDate = _selectedDay;
});
// print('...');
}
which after the date and time has been selected the value is formatted like in the picture bellow
Now i want to be able to set the Scheduled Notification using the value from the selection but not sure how to do it... i have installed Flutter_Local_Notification and have imported it to my main.dart, have set the permission in the manifest file and have also tried to initial the plugin like down bellow
FlutterLocalNotificationsPlugin fltrNotification;
String _selectedParam;
int val;
#override
void initState() {
super.initState();
var androidInitilize = new AndroidInitializationSettings('app_icon');
var iOSinitilize = new IOSInitializationSettings();
var initilizationsSettings =
new InitializationSettings(androidInitilize, iOSinitilize);
fltrNotification = new FlutterLocalNotificationsPlugin();
fltrNotification.initialize(initilizationsSettings,
onSelectNotification: notificationSelected);
}
and i have also added the app_icon.png to my drawable folder
i have tried to follow some tutorial on how to do it but most of them only show how to set the netification using seconds but for my own project i want to set the schedule for a particular day, hour and minute
please how can i achive that?
You can use this my helper class
class NotificationPlugin {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
var initializationSettings;
NotificationPlugin._() {
init();
}
init() async {
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
if (Platform.isIOS) {
_requestIOSPermission();
}
initializePlatformSpecifics();
}
initializePlatformSpecifics() {
var initializationSettingsAndroid = AndroidInitializationSettings(
'mipmap/ic_launcher'); // <- default icon name is #mipmap/ic_launcher
var initializationSettingsIOS =
IOSInitializationSettings(onDidReceiveLocalNotification: (int a, String b, String c, d) {});
var initializationSettings =
InitializationSettings(initializationSettingsAndroid, initializationSettingsIOS);
flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: (String s) {});
initializationSettings =
InitializationSettings(initializationSettingsAndroid, initializationSettingsIOS);
}
_requestIOSPermission() {
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()
.requestPermissions(alert: false, badge: true, sound: true);
}
setOnNotificationClick(Function onNotificationClick) async {
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onSelectNotification: (payload) async {
onNotificationClick(payload);
},
);
}
Future<void> showNotification(
{#required int id, #required String title, #required String body}) async {
var androidChannelSpecifics = AndroidNotificationDetails(
'CHANNEL_ID',
'CHANNEL_NAME',
'CHANNEL_DESCRIPTION',
importance: Importance.High,
priority: Priority.High,
);
var iosChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidChannelSpecifics,
iosChannelSpecifics,
);
await flutterLocalNotificationsPlugin.show(id, title, body, platformChannelSpecifics,
payload: id.toString());
}
Future<void> showScheduledNotification(
{#required int id,
#required String title,
#required String body,
#required String date}) async {
var scheduledNotificationDateTime = DateTime.parse(date);
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'your other channel id', 'your other channel name', 'your other channel description');
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
NotificationDetails platformChannelSpecifics =
NotificationDetails(androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.schedule(
id, '$title', ' $body', scheduledNotificationDateTime, platformChannelSpecifics,
androidAllowWhileIdle: true);
}
Future<void> removeNotifications() async {
await flutterLocalNotificationsPlugin.cancelAll();
}
}
NotificationPlugin notificationPlugin = NotificationPlugin._();
and then you can call
await notificationPlugin.showScheduledNotification(
id: 123,
title:"fancy title",
body: "data",
date: yourDate,
);
/////////////////////////////////
if you will not use the helper class
this is simply what you need
var scheduledNotificationDateTime = DateTime.parse(date); // replace whith your date
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'your other channel id', 'your other channel name', 'your other channel description');
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
NotificationDetails platformChannelSpecifics =
NotificationDetails(androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.schedule(
id, '$title', ' $body', scheduledNotificationDateTime, platformChannelSpecifics,
androidAllowWhileIdle: true);