Reputation: 189
I am developing an app that reminds elderly about their medication. and there are three types of medication, daily, weekly and monthly. it stored in Firebase Firestore
as medicationType
field.
Each medication can take once or twice or three or foure times a day and stored as medicationDose
field. Each dose stored in firstDose
, secondDose
, thirdDose
and fourthDose
fields. like this:
I want to send notification to user for each medication time, my notification
class :
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:rxdart/rxdart.dart';
import 'ReminderNotification.dart';
class NotificationModel{
final BehaviorSubject<ReminderNotification> didReceiveLocalNotificationSubject =
BehaviorSubject<ReminderNotification>();
final BehaviorSubject<String> selectNotificationSubject =
BehaviorSubject<String>();
Future<void> initNotifications(
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin) async {
var initializationSettingsAndroid = AndroidInitializationSettings('@mipmap/ic_launcher');
var initializationSettingsIOS = IOSInitializationSettings(
requestAlertPermission: false,
requestBadgePermission: false,
requestSoundPermission: false,
onDidReceiveLocalNotification:
(int id, String title, String body, String payload) async {
didReceiveLocalNotificationSubject.add(ReminderNotification(
id: id, title: title, body: body, payload: payload));
});
var initializationSettings = InitializationSettings(
initializationSettingsAndroid, initializationSettingsIOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: (String payload) async {
if (payload != null) {
debugPrint('notification payload: ' + payload);
}
selectNotificationSubject.add(payload);
});
}
Future<void> showNotification(
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin) async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
'0', 'Natalia', 'your channel description',
importance: Importance.Max, priority: Priority.High, ticker: 'ticker');
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0, 'Natalia title', 'plain body', platformChannelSpecifics,
payload: 'item x');
}
Future<void> turnOffNotification(
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin) async {
await flutterLocalNotificationsPlugin.cancelAll();
}
Future<void> turnOffNotificationById(
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin,
num id) async {
await flutterLocalNotificationsPlugin.cancel(id);
}
Future<void> scheduleNotification(
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin,
String id,
String title,
String body,
DateTime scheduledNotificationDateTime) async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
id,
'Reminder notifications',
'Remember about it',
icon: '@mipmap/ic_launcher',
priority: Priority.High,
);
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.schedule(0, title, body,
scheduledNotificationDateTime, platformChannelSpecifics);
}
Future<void> scheduleNotificationPeriodically(
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin,
String id,
String body,
RepeatInterval interval) async {
var androidPlatformChannelSpecifics = AndroidNotificationDetails(
id,
'Reminder notifications',
'Remember about it',
icon: '@mipmap/ic_launcher',
);
var iOSPlatformChannelSpecifics = IOSNotificationDetails();
var platformChannelSpecifics = NotificationDetails(
androidPlatformChannelSpecifics, iOSPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.periodicallyShow(
0, 'Reminder', body, interval, platformChannelSpecifics);
}
void requestIOSPermissions(
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin) {
flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>()
?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
}
}
My function for notification in Medication class
that uses Notification class
:
void _showNotifications(String date) async {
return await notificationOfMedication(date);
}
Future notificationOfMedication(String date) async{
if (medicationDose == "مرة واحدة في اليوم") { //that means once a day
String body= 'موعد تناول دواء $medName';
DateTime time1= DateTime.parse(DateFormat('$date hh:mm:ss').format(firstDoseForNotification));
await notification.scheduleNotification(flutterLocalNotificationsPlugin,randomId,title, body, time1 );
} else if (medicationDose == 'مرتان في اليوم') {//that means twice a day
String body1= 'موعد تناول الجرعة الأولى لدواء $medName';
String body2= 'موعد تناول الجرعة الثانية لدواء $medName';
DateTime time1= DateTime.parse(DateFormat('$date hh:mm:ss').format(firstDoseForNotification));
DateTime time2= DateTime.parse(DateFormat('$date hh:mm:ss').format(secondDoseForNotification));
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId, title,body1,time1 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body2,time2 );
} else if (medicationDose == "ثلاث مرات في اليوم") { //that means three times a day
String body1= 'موعد تناول الجرعة الأولى لدواء $medName';
String body2= 'موعد تناول الجرعة الثانية لدواء $medName';
String body3= 'موعد تناول الجرعة الثالثة لدواء $medName';
DateTime time1= DateTime.parse(DateFormat('$date hh:mm:ss').format(firstDoseForNotification));
DateTime time2= DateTime.parse(DateFormat('$date hh:mm:ss').format(secondDoseForNotification));
DateTime time3= DateTime.parse(DateFormat('$date hh:mm:ss').format(thirdDoseForNotification));
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body1,time1 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body2,time2 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body3,time3 );
}else if (medicationDose == "اربعة مرات في اليوم") { //that means four times a day
String body1= 'موعد تناول الجرعة الأولى لدواء $medName';
String body2= 'موعد تناول الجرعة الثانية لدواء $medName';
String body3= 'موعد تناول الجرعة الثالثة لدواء $medName';
String body4= 'موعد تناول الجرعة الرابعة لدواء $medName';
DateTime time1= DateTime.parse(DateFormat('$date hh:mm:ss').format(firstDoseForNotification));
DateTime time2= DateTime.parse(DateFormat('$date hh:mm:ss').format(secondDoseForNotification));
DateTime time3= DateTime.parse(DateFormat('$date hh:mm:ss').format(thirdDoseForNotification));
DateTime time4= DateTime.parse(DateFormat('$date hh:mm:ss').format(fourthDoseForNotification));
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body1,time1 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body2,time2 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body3,time3 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body4,time4 );
}
}
My entire Medication
class:
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:date_time_picker/date_time_picker.dart';
import 'package:elderly_app/Pages/logout.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import '../customizedWidgets/Constants.dart';
import '../customizedWidgets/addNavigationBar.dart';
import 'package:intl/intl.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import '../Notification/NotificationModel.dart';
import 'package:cron/cron.dart';
import 'package:flutter/cupertino.dart';
import 'dart:math';
class HomepageElderly extends StatefulWidget {
@override
_HomepageElderlyState createState() => _HomepageElderlyState();
}
class _HomepageElderlyState extends State<HomepageElderly> {
String finalDate = "";
String title= 'تذكير بموعد الدواء';
var randomId= Random().nextInt(10000).toString();
String watcherId = '';
final cron = Cron();
String medicationDose = 'مرة واحدة في اليوم';
String firstDose;
String secondDose;
String thirdDose;
String fourthDose;
String medicationType;
String medName=' ';
DateTime firstDoseForNotification= DateTime.now() ;
DateTime secondDoseForNotification= DateTime.now() ;
DateTime thirdDoseForNotification = DateTime.now();
DateTime fourthDoseForNotification= DateTime.now();
final NotificationModel notification = NotificationModel();
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
final user = FirebaseAuth.instance.currentUser;
Future getWatcherId() async{
if (user != null) {
await FirebaseFirestore.instance
.collection('users')
.doc(user.uid)
.get()
.then((data) {
if(!mounted) return;
setState(() {
watcherId = data.data()['watcherId'];
});
});
}
}
@override
void initState() {
getWatcherId();
super.initState();
notification.initNotifications(flutterLocalNotificationsPlugin);
notificationOfMedication(DateFormat('yyyy-MM-dd').format(DateTime.now()));
_showNotifications(DateFormat('yyyy-MM-dd').format(DateTime.now()));
}
void _showNotifications(String date) async {
return await notificationOfMedication(date);
}
Future notificationOfMedication(String date) async{
if (medicationDose == "مرة واحدة في اليوم") { //that means once a day
String body= 'موعد تناول دواء $medName';
DateTime time1= DateTime.parse(DateFormat('$date hh:mm:ss').format(firstDoseForNotification));
await notification.scheduleNotification(flutterLocalNotificationsPlugin,randomId,title, body, time1 );
} else if (medicationDose == 'مرتان في اليوم') {//that means twice a day
String body1= 'موعد تناول الجرعة الأولى لدواء $medName';
String body2= 'موعد تناول الجرعة الثانية لدواء $medName';
DateTime time1= DateTime.parse(DateFormat('$date hh:mm:ss').format(firstDoseForNotification));
DateTime time2= DateTime.parse(DateFormat('$date hh:mm:ss').format(secondDoseForNotification));
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId, title,body1,time1 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body2,time2 );
} else if (medicationDose == "ثلاث مرات في اليوم") { //that means three times a day
String body1= 'موعد تناول الجرعة الأولى لدواء $medName';
String body2= 'موعد تناول الجرعة الثانية لدواء $medName';
String body3= 'موعد تناول الجرعة الثالثة لدواء $medName';
DateTime time1= DateTime.parse(DateFormat('$date hh:mm:ss').format(firstDoseForNotification));
DateTime time2= DateTime.parse(DateFormat('$date hh:mm:ss').format(secondDoseForNotification));
DateTime time3= DateTime.parse(DateFormat('$date hh:mm:ss').format(thirdDoseForNotification));
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body1,time1 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body2,time2 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body3,time3 );
}else if (medicationDose == "اربعة مرات في اليوم") { //that means four times a day
String body1= 'موعد تناول الجرعة الأولى لدواء $medName';
String body2= 'موعد تناول الجرعة الثانية لدواء $medName';
String body3= 'موعد تناول الجرعة الثالثة لدواء $medName';
String body4= 'موعد تناول الجرعة الرابعة لدواء $medName';
DateTime time1= DateTime.parse(DateFormat('$date hh:mm:ss').format(firstDoseForNotification));
DateTime time2= DateTime.parse(DateFormat('$date hh:mm:ss').format(secondDoseForNotification));
DateTime time3= DateTime.parse(DateFormat('$date hh:mm:ss').format(thirdDoseForNotification));
DateTime time4= DateTime.parse(DateFormat('$date hh:mm:ss').format(fourthDoseForNotification));
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body1,time1 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body2,time2 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body3,time3 );
await notification.scheduleNotification(flutterLocalNotificationsPlugin, randomId,title, body4,time4 );
}
}
@override
Widget build(BuildContext context) {
return StreamBuilder<Object>(
stream: null,
builder: (context, snapshot) {
return Scaffold(
appBar: AppBar(actions: [Logout()], backgroundColor: nave),
bottomNavigationBar: AddNavigationBarPageElderly(),
body: StreamBuilder(
stream: FirebaseFirestore.instance
.collection('medicine')
.where('userId', isEqualTo: watcherId)
.snapshots(),
builder: (context, snapshot) {
if (snapshot.data == null) {
return Center(
child: CircularProgressIndicator(),
);
}
final doc = snapshot.data.docs;
return SizedBox(
height: 400.0,
child: ListView.builder(
itemCount: doc.length,
itemBuilder: (ctx, index) {
if(doc.length==0){
return Center( child: Text('لا يوجد هناك أدوية', style: TextStyle(color: nave, fontWeight: FontWeight.bold),));
}
medicationDose = doc[index]['medicationDose'];
firstDose = DateFormat('hh:mm a')
.format(doc[index]['firstDose'].toDate());
secondDose = DateFormat('hh:mm a')
.format(doc[index]['secondDose'].toDate());
thirdDose = DateFormat('hh:mm a')
.format(doc[index]['thirdDose'].toDate());
fourthDose = DateFormat('hh:mm a')
.format(doc[index]['fourthDose'].toDate());
DateTime startDate= doc[index]['medicationStartDate'].toDate();
DateTime endDate= doc[index]['medicationEndDate'].toDate();
medName= doc[index]['medicationName'];
medicationType=doc[index]['medicationType'];
firstDoseForNotification =doc[index]['firstDose'].toDate();
secondDoseForNotification = doc[index]['secondDose'].toDate();
thirdDoseForNotification = doc[index]['thirdDose'].toDate();
fourthDoseForNotification = doc[index]['fourthDose'].toDate();
String nameOfToday= DateFormat('EEEE').format(DateTime.now());
List<String> daysOfWeeklyMedication= [];
if(medicationType=='إسبوعيًا'){
bool isSat = doc[index]['isSat'];
bool isSun = doc[index]['isSun'];
bool isMon = doc[index]['isMon'];
bool isTue = doc[index]['isTue'];
bool isWed = doc[index]['isWed'];
bool isThu = doc[index]['isThu'];
bool isFri = doc[index]['isFri'];
if(isSat) daysOfWeeklyMedication.add('Saturday');
if(isSun) daysOfWeeklyMedication.add('Sunday');
if(isMon) daysOfWeeklyMedication.add('Monday');
if(isTue) daysOfWeeklyMedication.add('Tuesday');
if(isWed) daysOfWeeklyMedication.add('Wednesday');
if(isThu) daysOfWeeklyMedication.add('Thursday');
if(isFri) daysOfWeeklyMedication.add('Friday');
}
List<dynamic> daysOfMonthlyMedication=[];
if(medicationType=='شهريًا'){
final dates = doc[index]['selectedDates'];
daysOfMonthlyMedication = dates.map((date) => date.toDate()).toList();
//List<dynamic> daysOfMonthlyMedication = doc[index]['selectedDates'].toDate();
}
List<DateTime> daysOfStartAndEndMedication= [];
for (int i = 0; i <= endDate.difference(startDate).inDays; i++) {
daysOfStartAndEndMedication.add(startDate.add(Duration(days: i)));
}
for (int i = 0; i <daysOfStartAndEndMedication.length; i++) {
String medDate=DateFormat("yyyy-MM-dd").format(daysOfStartAndEndMedication[i]);
if(medicationType=='يوميًا'){
String date= DateFormat('yyyy-MM-dd').format(daysOfStartAndEndMedication[i]);
_showNotifications(date);
} else if(medicationType=='إسبوعيًا'){
for(int i=0; i<daysOfWeeklyMedication.length; i++){
if(daysOfWeeklyMedication[i] == daysOfStartAndEndMedication[i].day.toString()){
String date= DateFormat('yyyy-MM-dd').format(daysOfStartAndEndMedication[i]);
_showNotifications(date);
}
}
}else if(medicationType=='شهريًا'){
for(int i=0; i<daysOfMonthlyMedication.length; i++){
if(daysOfStartAndEndMedication[i].day == daysOfMonthlyMedication[i].day){
String date= DateFormat('yyyy-MM-dd').format(daysOfStartAndEndMedication[i]);
_showNotifications(date);
}
}}
}
return Center( child: Text('لا يوجد هناك أدوية'));
},
),
);
},
),
);
}
);
}
}
I really worked hard in it but it still not working, Can anyone help me? please
I used flutter_local_notifications: ^1.4.1
because I heard that newest version does not work.
Upvotes: 0
Views: 1509
Reputation: 187
I dont understand where is the problem exactly, but I will share you my way of handling notifications.
First
make class FirebaseServices FirebaseServices.dart
class FirebaseServices {
static final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
static final _fln = FlutterLocalNotificationsPlugin();
int _counter = 0; // id
Future<String> getFCMToken() async {
return await _firebaseMessaging.getToken();
}
static Future<void> init() async {
print("___FCMtoken: ${await _firebaseMessaging.getToken()}");
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print("___onMessage: $message");
// You can show the notification while application is running only,
// otherwise it will show automatically by system when u recive notification from Firebase Cloud Messaging (or any other service).
_showNotificationWithDefaultSound(message);
},
onLaunch: (Map<String, dynamic> message) async {
print("___onLaunch: $message");
_serialiseAndNavigate(message);
},
onResume: (Map<String, dynamic> message) async {
print("___onResume: $message");
_serialiseAndNavigate(message);
},
);
}
static Future initialiseLocalNotification() async {
/////// flutter local notification
// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project
var android = AndroidInitializationSettings('ic_logo');
var iOS = IOSInitializationSettings();
var platform = InitializationSettings(android: android, iOS: iOS);
await _fln.initialize(platform, onSelectNotification: onSelectNotification);
}
static void _serialiseAndNavigate(Map<String, dynamic> message) {
var notificationData = message[
'data']; // <This is an example only do it according to ur notification data>
print("___model: $notificationData");
//do ur code here
}
///You can contol how to show notification here.
static Future _showNotificationWithDefaultSound(
Map<String, dynamic> message) async {
var notificationData = message['data'];
print("___notificationData: $notificationData");
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
'default_notification_channel_id',
'default_notification_channel_id',
'your channel description',
importance: Importance.max,
priority: Priority.high,
);
var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
var platformChannelSpecifics = new NotificationDetails(
android: androidPlatformChannelSpecifics,
iOS: iOSPlatformChannelSpecifics,
);
await _fln.show(
_counter++, // id
'${message['notification']['title']}',
'${message['notification']['body']}',
platformChannelSpecifics,
payload: "notificationData", //<-- check documentation here
);
}
///This is when user click on notification.
static Future onSelectNotification(dynamic payload) async {
if (payload != null) {
print('___notification payload: ' + payload);
_serialiseAndNavigate(payload);
}
}
}
Second
make initialize it in any where in the app, I prefer to initialize it in main()
like this:
// initialize flutter local notifications here or in any other place in application.
WidgetsFlutterBinding.ensureInitialized();
FirebaseServices.init();
NOTE
Note that u should send the firebase token to ur backend server and handle each user with his token,..etc.
Notifications usually don't work properly on emulator/simulator so better use real device.
iOS will need some extra work to handle notifications (the payload usaually is different, configuration is different, etc)
Last
if u follow the code u should at least be able to test notifications through Firebase consol.
regards
Upvotes: 2