我正在开发一款应用,提醒老年人服用药物。并且有三种类型的药物,每天,每周和每月。它存储在 Firebase Firestore
作为 medicationType
字段。
每种药物可以每天服用一两次或三四次并存储为 medicationDose
字段。每个剂量存储在 firstDose
、secondDose
、thirdDose
和 fourthDose
字段中。像这样:
我想在每次服药时间向用户发送通知,我的 notification
班级:
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,
);
}
}
我在 Medication class
中使用 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 );
}
}
我的整个 Medication
班级:
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('لا يوجد هناك أدوية'));
},
),
);
},
),
);
}
);
}
}
我真的很努力,但还是不行,谁能帮帮我?请
我使用 flutter_local_notifications: ^1.4.1
是因为我听说最新版本不能用。
答案 0 :(得分:1)
我不明白问题究竟出在哪里,但我会与您分享我处理通知的方式。
第一
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);
}
}
}
第二
make 在应用程序的任何位置初始化它,我更喜欢在 main()
中初始化它
像这样:
// initialize flutter local notifications here or in any other place in application.
WidgetsFlutterBinding.ensureInitialized();
FirebaseServices.init();
注意
请注意,您应该将 firebase 令牌发送到您的后端服务器,并使用他的令牌等处理每个用户。
通知在模拟器/模拟器上通常无法正常工作,因此最好使用真实设备。
iOS 需要一些额外的工作来处理通知(通常负载不同、配置不同等)
最后
如果您遵循代码,您至少应该能够通过 Firebase consol 测试通知。
问候