Running specific function in background in an flutter application - flutter

I am developing a water remainder app in a flutter. I want a specific function to run on background even when the app is killed. I have a function that gives notification. I want that notification function to run on background even when the app is not running on the background, but I don't know where to call that function.
This is the notification function:
_scheduleNotify() async {
print("object");
flutterLocalNotificationsPlugin = new FlutterLocalNotificationsPlugin();
var android = new AndroidInitializationSettings('#mipmap/ic_launcher');
var ios = new IOSInitializationSettings();
var initsetting = new InitializationSettings(android, ios);
flutterLocalNotificationsPlugin.initialize(initsetting);
var scheduledNotificationDateTime =
new DateTime.now().add(new Duration(seconds: 5));
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
'your other channel id',
'your other channel name',
'your other channel description');
var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
NotificationDetails platformChannelSpecifics = new NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.schedule(
0,
'scheduled title',
'scheduled body',
scheduledNotificationDateTime,
platformChannelSpecifics);
}
I have called this function every time the user gives input of intake. This works fine until the app is running. But if the app is closed or killed. This is not working. So where should I call this function to make this run even when the app is killed?
I didn't get any resources to implement this and I am a beginner in a flutter. Can someone help me with this? Thanks in advance.

The recommendation from this SO post could be applicable to your case:
For reminders i would recommend Flutter Local Notifications
Plugin. It has
a powerful scheduling api. From the documentation of local
notification:
And for push notification, you can use Firebase Cloud
Messaging or one signal
plugin or you can
implement natively through
platform-channels
Edit: You can also fire notifications according to specific conditions
even if the app is terminated. This can be achieved by running dart
code in the background. Quoting from the official faq:

Related

Flutter: FCM background notification large icon

I'm using firebase_messaging and flutter_local_notifications for notifications, and I was able to show a large icon in case of local(foreground) notifications, but I didn't seem to find a way to show the same large icon when the app is background.
handle background noti and show noti using local notification.
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
This code help you to receive a Notification and to use in your app :
void initMessaging() {
var androiInit = AndroidInitializationSettings(‘#mipmap/ic_launcher’);//for logo
var iosInit = IOSInitializationSettings();
var initSetting=InitializationSettings(android: androiInit,iOS:
iosInit);
fltNotification = FlutterLocalNotificationsPlugin();
fltNotification.initialize(initSetting);
var androidDetails =
AndroidNotificationDetails(‘1’, ‘channelName’, ‘channel
Description’);
var iosDetails = IOSNotificationDetails();
var generalNotificationDetails =
NotificationDetails(android: androidDetails, iOS: iosDetails);
FirebaseMessaging.onMessage.listen((RemoteMessage message) { RemoteNotification notification=message.notification;
AndroidNotification android=message.notification?.android;
if(notification!=null && android!=null){
fltNotification.show(
notification.hashCode, notification.title, notification.
body, generalNotificationDetails);
}
});
}
If you have any difficulty, please check this article : Flutter Push Notification Medium.
Thanks.
A better way to use largeIcon is using the image property in notification payload when you are sending the notification:
const payload = {
notification: {
title: 'title',
body: 'description',
image: 'large_icon_url',
sound : "default"
},
};
1- use flutter_local_notifications in backgroundMessageHandler to display the image
2- remove the "notification" in the payload and add your data in
"data:{
title: 'title',
body: 'description',
image: 'image',
}"

Flutter Local Notifications doesn't execute code with app terminated

I have an app that schedules alarms, which trigger flutter local notifications. When pressing one of the buttons on these notifications, the database gets updated to reflect that you've turned off the alarm.
However, when the app is terminated/closed down, it seems as if no code gets executed and the database doesn't get updated.
The notification does get triggered, it's when the user presses a button inside of it that no code gets executed. Looks something like this
I'd like to know if what I'm trying is even possible, because at this point I'm not sure.
The notifications are created using the zonedSchedule from the flutter local notifications plugin.
The app does not get opened when pressing one of the buttons in the notification.
The code is as follows:
class LocalNoticationsService {
LocalNoticationsService(
this._notificationsPlugin,
);
final FlutterLocalNotificationsPlugin _notificationsPlugin;
Future<void> init() async {
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings(
'img/path',// path to notification icon
);
final DarwinInitializationSettings initializationSettingsIOS = DarwinInitializationSettings(
requestSoundPermission: false,
requestBadgePermission: false,
requestAlertPermission: false,
defaultPresentAlert: true,
defaultPresentSound: true,
notificationCategories: [
DarwinNotificationCategory(
'category',
options: {
DarwinNotificationCategoryOption.allowAnnouncement,
},
actions: [
DarwinNotificationAction.plain(
'snoozeAction',
'snooze',
),
DarwinNotificationAction.plain(
'confirmAction',
'confirm',
options: {
DarwinNotificationActionOption.authenticationRequired,
},
),
],
),
],
);
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await _notificationsPlugin.initialize(
initializationSettings,
onSelectNotification: _onSelectedNotification,
onSelectNotificationAction: onSelectNotificationAction,
);
final notificationOnLaunchDetails = await _notificationsPlugin.getNotificationAppLaunchDetails();
if (notificationOnLaunchDetails?.didNotificationLaunchApp ?? false) {
_onSelectedNotification(notificationOnLaunchDetails!.payload);
}
}
void _onSelectedNotification(String? payload) {
// Not relevant to this problem
}
Future<bool> _confirmAlarm(AlarmPayLoad alarmPayload) async {
// Update database
}
}
// Top level function
Future<void> onSelectNotificationAction(NotificationActionDetails details) async {
await Firebase.initializeApp();
final localNotificationsService = LocalNoticationsService(
FlutterLocalNotificationsPlugin()
);
await localNotificationsService.init();
final alarmPayload = AlarmPayLoad.fromJson(details.payload);
await localNotificationsService._confirmAlarm(alarmPayload)
}
Due to this all running in the background, I've been unable to find a way to log things. I've tried using the http package to send post request to a webhook with some data, but these do not seem to trigger when the app is terminated, but do work when in the app is in the foreground or in the background(not closed).
Any post or videos I've found online about flutter local notifications don't seem to cover this problem or are using firebase push notifications and the associated package for background handling.
I'd be very interested to hear any feedback on what might be going wrong or what might be the solution and how handling background notifications works. If you need additional information on the code, feel free to ask.
If you want to run it on background, follow the link here.

How to change notification data like title and body, when using flutter_local_notification plugin?

I am currently using the flutter_local_notifications plugin to trigger notifications but the problem is that I want to dynamically change the notification title and its body. Basically, I am creating new notifications on my Django Backend and then fetching the latest notification data in my flutter frontend. The notification is triggered on daily basis but the notification title and body are not changing. The sample code snippet is as follow:
var res = await http.get(Uri.parse(<REST API ENDPOINT>));
var body = await json.decode(res.body);
Map notificationData = body['results'][0];
await flutterLocalNotificationsPlugin.periodicallyShow(
notificationData['id'],
notificationData['title'],
notificationData['body'],
RepeatInterval.daily,
notificationDetails);
Basically, I want to fetch the latest notification from the backend before triggering each notification and use the latest data i.e. title and body.
Basically, I want to fetch the latest notification from the backend before triggering each notification and use the latest data i.e. title and body
Then this means it's not a periodic notification. You should show a regular notification.
from docs note the repeating title and body
await flutterLocalNotificationsPlugin.periodicallyShow(0, 'repeating title',
'repeating body', RepeatInterval.everyMinute, platformChannelSpecifics,
androidAllowWhileIdle: true);
you should fetch you data and show a notification
await flutterLocalNotificationsPlugin.show(
0, 'plain title', 'plain body', platformChannelSpecifics,
payload: 'item x');

How can i send birthday wishes notifciations to user automatically when the day comes using Flutter

In my flutter app i am collecting the date of birth of user , now i want to send them birthday wishes as push notifications when the day comes , the notifications should be sent even when the user doesnt uses the app , like facebook ,gmail sends.
Someone suggested me of using broadcast for this , but as a beginner in flutter i cannot find a way about how to use it , or can someone please suggest another solution for it.
I used flutter_local_notifications as i implemented it in one of my pages it can only be triggered when user runs the app , whereas i want wishes to be sent automatically.
It will be very helpful if someone helped me out here.
Integrate firebase and there is a too Firebae cloud messaging or you can have your own site and implement it. However, cloud messaging is free.
You can take two ways: You do it from remote on your server than you send a notification (For istance by using Firebase) or you schedule a notification with flutter_local_notification.
I'll post you an example by using flutter_local_notification:
Let's say your user inputs something like DateTime birthday = DateTime(1996, 12, 12). Than you trigger the following:
int currentAge = DateTime.now().year - birthday.year;
//Notification setup
AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails('your channel id',
'your channel name', 'your channel description');
IOSNotificationDetails iOSPlatformChannelSpecifics =
IOSNotificationDetails();
NotificationDetails platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
//Iterate for 20 years
for(int i = 0; i<20; i++){
await flutterLocalNotificationsPlugin.schedule(
0,
'scheduled title',
'scheduled body',
birthday.add(Duration(years: currentAge+i)),
platformChannelSpecifics);
}
Done :)
Ps. Be carefull: DateTime contains also Hour, Minute, Seconds and microseconds. So, if you schedule it, do it properly.
Use this package,
flutter_local_notification
You can use it like this and use some kind of key value storage to check for which date/year it has been set and based on this check you could reset the notification for next year and so on.
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
initialize() async {
// This is how you initialize the local notification package in flutter.
// Please follow the link above to setup iOS and Android specify permission and configuration.
var initializationSettingsAndroid =
AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = IOSInitializationSettings(
onDidReceiveLocalNotification: onDidReceiveLocalNotification,
);
var initializationSettings = InitializationSettings(
initializationSettingsAndroid,
initializationSettingsIOS,
);
await flutterLocalNotificationsPlugin.initialize(
initializationSettings,
onSelectNotification: onSelectNotification,
);
}
Future<void> scheduleUserBirthdayNotification({DateTime dob}) async {
// nScheduledDobId is your notification id should be integer.
// cancel the previous one before setting for next year.
await cancelNotification(withId: nScheduledDobId);
DateTime commingDate = DateTime.now();
final scheduledNotificationDateTime =
DateTime(commingDate.year, dob.month, dob.day, 6);
await scheduleNotification(
id: nScheduledDobId,
title: 'Happy Birthday! 🎂',
scheduledNotificationDateTime: scheduledNotificationDateTime,
body:
"We hope your special day will bring you lots of happiness, love, and fun.",
);
await KeyValueStorage().setDobNotificationDate(
scheduledNotificationDateTime,
);
}

How to add android notification channel id for flutter app to fix notification while app is on background

In my flutter app the function onResume and onLunch not working on android platform, while they work fine on IOS,
i receive the following message on console instead of printed strings in those functions:
"W/FirebaseMessaging(24847): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used."
onMessage function works fine, the problem is when the app is in background
my guess is that it has something to do with android notification channel id which should be added in android manifest
when i add that to manifest with adding the following code to AndroidManifest the message change to :
(I added a strings.xml file in values and defined "default_notification_channel_id" there.)
"Notification Channel set in AndroidManifest.xml has not been created by the app. Default value will be used."
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="#string/default_notification_channel_id"/>
in my console i should receive onResume and onLunch strings which i printed , but instead i receive following messages :
"W/FirebaseMessaging(24847): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used."
"Notification Channel set in AndroidManifest.xml has not been created by the app. Default value will be used."
<meta-data android:name="com.google.firebase.messaging.default_notification_channel_id" android:value="#string/default_notification_channel_id"/>
You should create a notification channel first, the plugin: flutter_local_notifications can create and remove notification channels.
First, initialize the plugin:
Future<void> initializeLocalNotifications() async {
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
// app_icon needs to be a added as a drawable resource to the
// Android head project
var initializationSettingsAndroid = AndroidInitializationSettings('app_icon');
var initializationSettingsIOS = IOSInitializationSettings(
onDidReceiveLocalNotification: onDidReceiveLocalNotification);
var initializationSettings = InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
}
Second, create notification channel using this plugin:
Future<void> _createNotificationChannel(String id, String name,
String description) async {
final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
var androidNotificationChannel = AndroidNotificationChannel(
id,
name,
description,
);
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(androidNotificationChannel);
}
Now you have two options:
Create a channel with the default id you already defined in AndroidManifest.xml
Choose your own channel ids and send each notification to a specific channel by embedding the channel id into your FCM notification message. To do so, add channel_id tag to your notification under notification tag, under android tag.
Here is a sample notification message from Firebase Functions with custom notification channel id:
'notification': {
'title': your_title,
'body': your_body,
},
'android': {
'notification': {
'channel_id': your_channel_id,
},
},
have you created default_notification_channel_id ?
"W/FirebaseMessaging(24847): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used."
You have this warning when you don't set the channel_id in the payload of the notification