Call a HTTP request in flutter local notification - android

I would like to ask if there's a http get in flutter local notifications? My aim here is when the flutter notification will show, a http get request will be triggered
This my http request for my api:
final String url = 'http://192.168.43.45:8000/api';//url in my request
List data;
Future<String> getData() async {
var response =await http.get(
Uri.encodeFull(url),
headers:{"Accept":"application/json"}
);//get data and decode it to json
}
This code will initialize the notifications:
initializeNotifications() async {
var initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/launcher_icon');//icon will display when notification appears
var initializationSettingsIOS = IOSInitializationSettings();
var initializationSettings = InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
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) => HomePage()),
);
}
Code for the notification when click it will redirect to homePage:
Future<void> scheduleNotification(Medicine medicine) async {
var hour = int.parse(medicine.startTime[0] + medicine.startTime[1]);
var ogValue = hour;
var minute = int.parse(medicine.startTime[2] + medicine.startTime[3]);
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'repeatDailyAtTime channel id',
'repeatDailyAtTime channel name',
'repeatDailyAtTime description',
importance: Importance.Max,
ledColor: Color(0xFF3EB16F),
ledOffMs: 1000,
ledOnMs: 1000,
enableLights: true,
);
//notification details
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
//this code will show the whats the notification must appear
await flutterLocalNotificationsPlugin.showDailyAtTime(
int.parse(medicine.notificationIDs[i]),
'Mediminder: ${medicine.medicineName}',
medicine.medicineType.toString() !=
MedicineType.None.toString()
? 'It is time to take your Medicine, according to schedule'
: 'It is time to take your medicine, according to schedule',
Time(hour, minute,),
platformChannelSpecifics);
hour = ogValue;
}
//await flutterLocalNotificationsPlugin.cancelAll();//cancel the flutter notifications
}
}

it seems that you are using flutter_local_notifications, looking at their documentation i don't think it's possible to you to handle the onReceive notification, this is done internally by the package.
But maybe you could implement your own receiver class extending BroadCastReceiver and listen for the same action that the packages send, from there you'll be able to send HTTP requests.
Take a look at this question, maybe it helps.

Related

Firebase Messaging - Validate incoming background messages based on user logged in

I'm creating a chat app (kind of WhatsApp-like messaging) using Flutter.
First, the notifications mechanism is working as intended, whenever I send a message from 1 device to another device, the notification would pop up.
I created a local_notification_service.dart to handle the foreground notification & sending a not
import 'dart:math';
import 'package:get/get.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
class LocalNotificationService extends GetConnect {
String serverKey ='xxxxxxxxxxxxxxxxxxxx'
static final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
static void initialize() {
const InitializationSettings initializationSettings = InitializationSettings(android: AndroidInitializationSettings("#mipmap/ic_launcher"));
_flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
static void display(RemoteMessage message) async {
try {
print("Display notification");
// int id = DateTime.now().microsecondsSinceEpoch ~/1000000;
Random random = Random();
int id = random.nextInt(1000);
const NotificationDetails notificationDetails = NotificationDetails(
android: AndroidNotificationDetails(
"mychanel",
"my chanel",
importance: Importance.max,
priority: Priority.high,
));
print("my id is ${id.toString()}");
await _flutterLocalNotificationsPlugin.show(
id,
message.notification!.title,
message.notification!.body,
notificationDetails,
);
} on Exception catch (e) {
print('Error>>>$e');
}
}
Future<void> sendNotification({
String? title,
String? message,
String? token,
String? uniqueId,
String? action,
String? channelId,
String? channelName,
String? channelDesc,
}) async {
final data = {
"click_action": "FLUTTER_NOTIFICATION_CLICK",
"action": action,
"uniqueId": uniqueId,
"message": message,
"channelId": channelId ?? 'my channel id',
"channelName": channelName ?? 'my channel Name',
"channelDesc": channelDesc ?? 'my channel description',
};
try {
final response = await post(
'https://fcm.googleapis.com/fcm/send',
{
'notification': {'title': title, 'body': message},
'priority': 'high',
'data': data,
'to': '$token',
'direct_boot_ok': true,
},
headers: {
'Content-Type': 'application/json',
'Authorization': 'key=$serverKey',
},
);
print('response body : ${response.body}');
} catch (e) {}
}
}
Then, I'm trying to validate the users in my flutter application whenever they receive FCM notification, here's the logic that I want to create:
If the user is not logged in, then the device could not receive the notification
If the user is logged in, but the specific user is not eligible to receive the message (in case there are some users with the same FCM token / device registered ) then the device could not receive the notification. I would want to solve this after the point number 1 is succeeded
Here's my main.dart file
void main() async {
await GetStorage.init();
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
GlobalController globalC = Get.put(GlobalController());
AuthController authC = Get.put(AuthController());
ErrorController errorC = Get.put(ErrorController());
ConnectivityResult connectivityResult = ConnectivityResult.none;
final Connectivity connectivity = Connectivity();
connectivityResult = await connectivity.checkConnectivity();
if (connectivityResult == ConnectivityResult.wifi || connectivityResult == ConnectivityResult.mobile) {
// Start FCM
final fcmToken = await FirebaseMessaging.instance.getToken();
globalC.fcmToken.value = fcmToken ?? ''; //set global fcm Token
final FirebaseMessaging fcmInstance = FirebaseMessaging.instance;
NotificationSettings settings = await fcmInstance.requestPermission(
alert: true,
announcement: true,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
await FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
/* Handle message when in foreground */
FirebaseMessaging.onMessage.listen((event) {
if (globalC.isAuthenticated.isTrue) {
LocalNotificationService.display(event); //display notification
}
});
/* Handle message when in background */
if (globalC.isAuthenticated.isTrue) {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}
fcmInstance.onTokenRefresh.listen((fcmToken) {
// Note: This callback is fired at each app startup and whenever a new
// token is generated.
}).onError((err) {
// Error getting token.
});
// End FCM
}
FirebaseAnalytics analytics = FirebaseAnalytics.instance;
runApp(MyApp());
}
as you can see, I'm trying to filter the non logged in user when in the foreground using the FirebaseMessaging.onMessage.listen with the globalC.isAuthenticated.isTrue validation. And it works (because the default of globalC.isAuthenticated is false whenever user is not logged in)
But for the FirebaseMessaging.onBackgroundMessage function does not seems to work with the validation. I've tried to search for the solution in the documentations, youtube but i couldn't find it till this question is made.
How can I make this kind of validation for background message?
Sorry for this newbie question, any help would be greatly appreciated.
Thank you .

Flutter WorkManager And PushNotification Callback Execution Issue

I am working on work manager to fetxh api data and initiate a notification in flutter,
//this is the name given to the background fetch
const simplePeriodicTask = "simplePeriodicTask";
Workmanager workmanager = Workmanager();
// flutter local notification setup
Future initializeWorkManagerAndPushNotification() async {
await workmanager.initialize(
callbackDispatcher,
isInDebugMode: false,
); //to true if still in testing lev turn it to false whenever you are launching the app
await workmanager.registerPeriodicTask(
"1", simplePeriodicTask,
existingWorkPolicy: ExistingWorkPolicy.replace,
frequency: Duration(minutes: 1), //when should it check the link
initialDelay:
Duration(seconds: 5), //duration before showing the notification
constraints: Constraints(
networkType: NetworkType.connected,
),
);
}
void callbackDispatcher() async {
workmanager.executeTask((task, inputData) async {
print('Ruuning - callbackDispatcher');
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
var androidSettings = AndroidInitializationSettings('#mipmap/ic_launcher');
var iOSSettings = IOSInitializationSettings();
var initSetttings =
InitializationSettings(android: androidSettings, iOS: iOSSettings);
//
// TODO: Permission
//
await flutterLocalNotificationsPlugin.initialize(initSetttings);
String message =
await WebServiceController.getInstance.getPushNotificationMessage();
print("here 1 ================");
// print(response);
// var convert = json.decode(response.body);
// if (convert['status'] == true) {
// showNotification(convert['msg'], flutterLocalNotificationsPlugin);
// } else {
// print("no messgae");
// }
print("messgae");
print(message);
await showNotification(message, flutterLocalNotificationsPlugin);
return Future.value(true);
});
}
Future showNotification(payloadmessage, flutterLocalNotificationsPlugin) async {
print("showing notification");
var androidDetails = AndroidNotificationDetails(
'channel id', 'channel NAME', 'CHANNEL DESCRIPTION',
priority: Priority.high, importance: Importance.max);
var iOSDetails = IOSNotificationDetails();
var platform = NotificationDetails(android: androidDetails, iOS: iOSDetails);
await flutterLocalNotificationsPlugin.show(
0, 'Message - Virtual intelligent solution', '$payloadmessage', platform,
payload: 'OnClick Payload -VIS \n $payloadmessage');
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
await initializeWorkManagerAndPushNotification();
runApp(MyApp());
}
this function callbackDispatcher() function is used to Initialize Notification and fetch api data from below method.
Future<String> getPushNotificationMessage() async {
print("getting - getPushNotificationMessage");
try {
var response = await _dio.get(APIURLConstants.pushNotification);
print(response);
print("here================ ${response.data}");
var convert = json.decode(response.data);
return convert['message'].toString() ?? "";
} on DioError catch (error) {
print("Dio Error ${error.message}");
} catch (error) {
print("Error - ${error.toString()}");
}
}
as per the below output , It seems that only print(response); of getPushNotificationMessage() is executed after that below code is not executing,
Performing hot restart...
Restarted application in 2,266ms.
W/WM-WorkSpec(31092): Interval duration lesser than minimum allowed value; Changed to 900000
I/flutter (31092): getting - getPushNotificationMessage
I/flutter (31092): {"message":"Hi There I am notification","seen":0,"notification_id":"111"}
I/WM-WorkerWrapper(31092): Worker result SUCCESS for Work [ id=6c935b3b-bfe4-47fa-b30a-0965299f5224, tags={ be.tramckrijte.workmanager.BackgroundWorker } ]
I founded the issue, to make the code execute, I needed to hot restart the application to execute code from
main() method

How to schedule a single local notification multiple times in Flutter

I've been working on the Flutter project and now I am trying to schedule notification by using flutter_local_notification. I've integrated that dependency into my project and it works fine.
Now I want to schedule a notification to be alerted on the app like 2 days before, and then 4 hours before, and then 30 minutes before.
For example, my app has an event called A, and then I want to schedule that event A to send a notification for the user like 1 day before, and then 1 hour before, and then 30 minutes before the event A starts. So it will send a notification 3 times.
For my scenario: In order to send a notification we have to pass the notification id. Let's consider event A has id '123'. Do I have to schedule that notification 3 times with the same notification id '123'?
Let's check the code I have done in order to send a notification:
Future<void> showNotification({
#required int id,
#required DateTime dateTime,
String title,
String body,
}) async {
final TimeZone timeZone = TimeZone();
final String tzName = await timeZone.getTimeZoneName();
final tz.Location location = await timeZone.getLocation(tzName);
final scheduledDate = tz.TZDateTime(
location,
dateTime.year,
dateTime.month,
dateTime.day,
dateTime.hour,
dateTime.minute,
dateTime.second,
);
log('------------> Schedule date $scheduledDate');
final AndroidNotificationDetails androidChannelSpecifics =
AndroidNotificationDetails(
'$id',
'NAME $id',
'DESCRIPTION $id',
importance: Importance.max,
priority: Priority.high,
ledOnMs: 1000,
ledOffMs: 500,
);
final IOSNotificationDetails iosNotificationSpecifics =
IOSNotificationDetails();
final notificationDetails = NotificationDetails(
iOS: iosNotificationSpecifics, android: androidChannelSpecifics);
await flutterLocalNotificationsPlugin.zonedSchedule(
id,
title,
body,
scheduledDate,
notificationDetails,
matchDateTimeComponents: DateTimeComponents.time,
uiLocalNotificationDateInterpretation: null,
androidAllowWhileIdle: true,
);
}
For notification initialization like configuring in AndroidManifest.xml, I also have done it already.
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
final BehaviorSubject<ReceivedNotification> didReceivedNotificationSub =
BehaviorSubject<ReceivedNotification>();
InitializationSettings initializationSettings;
LocalNotificationiHelper._() {
init();
}
Future<void> init() async {
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
tz.initializeTimeZones();
if (Platform.isIOS) {
_requestIOSPermission();
}
initialPlatformSpecifics();
}
void initialPlatformSpecifics() {
const AndroidInitializationSettings initializeAndroidSetting =
AndroidInitializationSettings('#mipmap/ic_launcher');
final IOSInitializationSettings initializeIOSSetting =
IOSInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: false,
onDidReceiveLocalNotification:
(int id, String title, String body, String payload) async {
final ReceivedNotification receivedNotification = ReceivedNotification(
id: id, title: title, body: body, payload: payload);
didReceivedNotificationSub.add(receivedNotification);
},
);
initializationSettings = InitializationSettings(
android: initializeAndroidSetting, iOS: initializeIOSSetting);
}
void _requestIOSPermission() {
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
.requestPermissions(
alert: false,
badge: true,
sound: true,
);
}
You might've noticed the class TimeZone(), it is just another class that I created to get the current time zone of the user.
Here is the class for TimeZone()
class TimeZone {
factory TimeZone() => _this ?? TimeZone._();
TimeZone._() {
initializeTimeZones();
}
static TimeZone _this;
Future<String> getTimeZoneName() async =>
FlutterNativeTimezone.getLocalTimezone();
Future<t.Location> getLocation([String timeZoneName]) async {
if (timeZoneName == null || timeZoneName.isEmpty) {
timeZoneName = await getTimeZoneName();
}
return t.getLocation(timeZoneName);
}
}
For example, event A with id 123 will start at 2020-11-19 16:00:00.
So I want to know that should we schedule that notification 3 times in order for it to be sent like 1 day before, 3 hours before, and 30 minutes before the event start??
This depends on how you'd like to set the interval. One way that you can schedule recurring notifications using flutter_local_notifications is by utilizing flutterLocalNotificationsPlugin.periodicallyShow() where you can set intervals like RepeatInterval.everyMinute - usage can be found in the docs.

How to enable the "Show Notification as Pop Up" by default on android devices?

I am working on a food delivery app with Flutter. I have recently Implemented the flutter_local_notifications and the notification is working fine. But there's one problem is that the notification doesn't show as pop up by default. The "Show as pop up" option is disabled by default in the notification settings.
Is there any way that when the app is installed the "Show as pop up" option is enabled by default.
Here's my Notification Configuration Code:
void registerNotification() {
// This function registers the user for recieving push notifications.
// After registering the user, it creates a new field inside 'userForChat' Database
// The field is called : 'pushToken' which is later used on to configure Firebase Automatic Cloud Messaging
firebaseMessaging.requestNotificationPermissions();
firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) {
print('onMessage: $message');
Platform.isAndroid
? showNotification(message['notification'])
: showNotification(message['aps']['alert']);
return;
},
onResume: (Map<String, dynamic> message) {
print('onResume: $message');
return;
},
onLaunch: (Map<String, dynamic> message) {
print('onLaunch: $message');
return;
},
);
// Token for Firebase Messaging
firebaseMessaging.getToken().then((token) {
print('token: $token');
Firestore.instance
.collection('usersForChat')
.document(currentUserId)
.updateData(
{'pushToken': token}); //Sets the firebase Token into the database
}).catchError((onError) {
setState(() {});
});
}
void configLocalNotification() {
var initializationSettingsAndroid = AndroidInitializationSettings(
'mipmap/ic_launcher');
var initializationSettingsIOS = IOSInitializationSettings();
var initializationSettings = InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
flutterLocalNotificationsPlugin.initialize(initializationSettings);
}
void showNotification(message) async {
// This function takes the notfication message as input triggers the notification to show the message.
// The input is in a json format so you have to decode the json with dart:convert.
// IMPORTANT: Specify the Application package name according to the OS.
//For Android, Use the android app package name from firebase
//For iOS, Use the iOS app package name from firebase
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
// add your apps package name for each OS(Android:iOS)
Platform.isAndroid
? 'com.jexmovers.app' //Update the package name to your app's package names
: 'com.jexmovers.ios', //Update the package name to your app's package names
'JexMovers Chat',
'App that lets you contact with your food delivery person',
playSound: true,
enableVibration: true,
importance: Importance.Max,
priority: Priority.Max,
visibility: NotificationVisibility.Public,
enableLights: true,
);
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
print(message);
print(message['body'].toString());
print(json.encode(message));
await flutterLocalNotificationsPlugin.show(
0,
message['title'].toString(),
message['body'].toString(),
platformChannelSpecifics,
payload: json.encode(message),
);
}

flutterLocalNotificationsPlugin.show

My flutter app, show this notification when FCM is triggered.
await flutterLocalNotificationsPlugin.show(
0, "my app. Alert", "Alert text from App", platform
);
Is there any way to show a image in the notification bar and not only the text?
Something like:
await flutterLocalNotificationsPlugin.show(
0, "my app. Alert", "Alert text from App","url: myimage.com/sample.jpg", platform
);
Thanks
If you are using the flutter_local_notifications plugin, then you can do something like this for android:
Future<void> _showBigPictureNotification() async {
var largeIconPath = await _downloadAndSaveImage(
'http://via.placeholder.com/48x48', 'largeIcon');
var bigPicturePath = await _downloadAndSaveImage(
'http://via.placeholder.com/400x800', 'bigPicture');
var bigPictureStyleInformation = BigPictureStyleInformation(
bigPicturePath, BitmapSource.FilePath,
largeIcon: largeIconPath,
largeIconBitmapSource: BitmapSource.FilePath,
contentTitle: 'overridden <b>big</b> content title',
htmlFormatContentTitle: true,
summaryText: 'summary <i>text</i>',
htmlFormatSummaryText: true);
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'big text channel id',
'big text channel name',
'big text channel description',
style: AndroidNotificationStyle.BigPicture,
styleInformation: bigPictureStyleInformation);
var platformChannelSpecifics =
NotificationDetails(androidPlatformChannelSpecifics, null);
await flutterLocalNotificationsPlugin.show(
0, 'big text title', 'silent body', platformChannelSpecifics);
}
For more such examples, please refer the official example provided by the plugin developer, here.

Categories

Resources