如何使用颤振本地通知推送通知?我的不起作用

时间:2021-04-20 00:03:50

标签: firebase flutter push-notification notifications localnotification

我正在开发一款应用,提醒老年人服用药物。并且有三种类型的药物,每天,每周和每月。它存储在 Firebase Firestore 作为 medicationType 字段。 每种药物可以每天服用一两次或三四次并存储为 medicationDose 字段。每个剂量存储在 firstDosesecondDosethirdDosefourthDose 字段中。像这样: enter image description here

我想在每次服药时间向用户发送通知,我的 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 是因为我听说最新版本不能用。

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 测试通知。

问候