Flutter notification issues

We are working on a** flutter app **that allow users to schedule a medicine reminder so they can add the name and the dosage,etc…, and the times they want to get notified so we tried to use awesome notification package and implement it but the notifications didn’t come so what we can do ? (we used firebase firestore to store data)

here is a snippet of code for the notification setup :

import 'package:awesome_notifications/awesome_notifications.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fireproject/Medicine_log/models/medicine.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'package:fireproject/Medicine_log/models/medicine.dart';

// Notification service class for managing and scheduling notifications.
class NotificationService {
  // Firestore instance for fetching medication data.
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;
  // Variable to keep track of notification IDs.
  int _notificationId = 0;

  // Constructor to initialize time zones for scheduling.
  NotificationService() {
    tz.initializeTimeZones();
  }

  // Method to handle events when a notification is created.
  @pragma('vm:entry-point')
  static Future<void> onNotificationCreatedMethod(
      ReceivedNotification receivedNotification) async {}

  // Method to handle events when a notification is displayed.
  @pragma('vm:entry-point')
  static Future<void> onNotificationsDisplayedMethod(
      ReceivedNotification receivedNotification) async {}

  // Method to handle events when a notification dismiss action is received.
  @pragma('vm:entry-point')
  static Future<void> onDismissActionReceivedMethod(
      ReceivedAction receivedAction) async {}

  // Method to handle events when a user taps on a notification or action button.
  @pragma('vm:entry-point')
  static Future<void> onActionReceiveMethod(
      ReceivedAction receivedAction) async {}

  // Method to schedule notifications based on the medicine data.
  Future<void> scheduleNotificationsBasedOnMedicine() async {
    // Set the timezone location for scheduling.
    final location = tz.getLocation('Asia/Amman');

    // Fetch all medicines from Firestore.
    QuerySnapshot querySnapshot = await _firestore.collection('medicine').get();

    for (var doc in querySnapshot.docs) {
      Medicine medicine = Medicine.fromFirestore(doc);

      // Loop through each reminder time for the medicine.
      for (var reminderTimestamp in medicine.reminderTime) {
        DateTime utcScheduledTime = reminderTimestamp.toDate();
        tz.TZDateTime scheduledTime =
            tz.TZDateTime.from(utcScheduledTime, location);

        // Schedule the notification.
        await AwesomeNotifications().createNotification(
          content: NotificationContent(
            id: _notificationId++, // Incrementing ID for each notification.
            channelKey: 'basic_channel',
            title: 'Medicijne Herinnering', // Title for the notification.
            body:
                '${medicine.dosage} ${medicine.name} innemen.', // Body text for the notification.
          ),
          schedule: NotificationCalendar.fromDate(
              date: scheduledTime), // Scheduling details.
        );
      }
    }
  }
}




and this is for add reminder page :

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:fireproject/notification/notification_serivce.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:intl/intl.dart';
import 'package:fireproject/Medicine_log/models/medicine.dart';
import 'package:fireproject/Medicine_log/widgets/time_input.dart';
import 'package:fireproject/Medicine_log/widgets/medication_card.dart';
import 'package:multi_select_flutter/multi_select_flutter.dart';
import '../widgets/date_selector.dart';
import '../widgets/footer.dart';
import '../widgets/input_style.dart';
import '../services/medication_service.dart';
import 'package:timezone/timezone.dart' as tz;

class medScreen extends StatefulWidget {
  final Medicine? medicineToEdit;
  const medScreen(
      {super.key, this.medicineToEdit}); // Constructor for HomeScreen

  @override
  State<medScreen> createState() => _HomeScreenState();
}

// FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
//     FlutterLocalNotificationsPlugin();

class _HomeScreenState extends State<medScreen> {
  final GlobalKey<FormState> _formKey =
      GlobalKey<FormState>(); // Form key for validation
  final ValueNotifier<int> selectedImageIndexNotifier = ValueNotifier<int>(-1);
  final List<String> _allDays = [
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday',
    'Sunday',
  ];

  // List of image URLs for medication images
  List imageUrls = [
    'assets/images/—Pngtree—pharmacy drug health tablet pharmaceutical_6861618.png',
    'assets/images/black-outlined-bottle.png',
    'assets/images/black-outlined-pill.png',
    'assets/images/blue-pill.png',
    'assets/images/blue-yellow-tablet.png',
    'assets/images/colored-bottle.png',
    'assets/images/green-pill.png',
    'assets/images/orange-tablet.png',
    'assets/images/pink-pill.png',
    'assets/images/pink-tablet.png',
    'assets/images/white-tablet.png',
  ];

  // Controllers for medication input fields
  final TextEditingController _medicationNameController =
      TextEditingController();
  final TextEditingController _quantityController = TextEditingController();
  final TextEditingController _doseController = TextEditingController();

  List<String> _selectedDays = []; // List to store selected days
  List<Timestamp> _reminderTimes = []; // List to store reminder times
  String selectedImageUrl = ''; // Selected medication image URL

  DateTime _selectedDate = DateTime.now(); // Selected date for medication

  // Function to show the medication input form as a bottom sheet
  void _showFormBottomSheet() {
    showModalBottomSheet(
      context: context,
      isScrollControlled: true,
      builder: (BuildContext context) {
        return _buildMedicationFormSheet(context);
      },
    );
  }

  // Future<void> _initializeLocalNotifications() async {
  //   const AndroidInitializationSettings initializationSettingsAndroid =
  //       AndroidInitializationSettings('app_icon');

  //   final InitializationSettings initializationSettings =
  //       InitializationSettings(
  //     android: initializationSettingsAndroid,
  //   );
  //   await flutterLocalNotificationsPlugin.initialize(
  //     initializationSettings,
  //   );
  // }

  // Future<void> _scheduleMedicationNotifications(
  //     List<Timestamp> reminderTimes) async {
  //   for (var time in reminderTimes) {
  //     final dateTime = time.toDate();
  //     await flutterLocalNotificationsPlugin.zonedSchedule(
  //       0,
  //       'Medication Reminder',
  //       'Time to take your medication',
  //       tz.TZDateTime.from(dateTime, tz.local),
  //       const NotificationDetails(
  //         android: AndroidNotificationDetails(
  //           'your channel id',
  //           'your channel name',
  //           importance: Importance.max,
  //           priority: Priority.high,
  //         ),
  //       ),
  //       androidAllowWhileIdle: true,
  //       uiLocalNotificationDateInterpretation:
  //           UILocalNotificationDateInterpretation.absoluteTime,
  //     );
  //   }
  // }

  // Function to update the reminder times
  void _updateReminderTime(List<Timestamp> times) {
    setState(() {
      _reminderTimes = times;
    });
  }

  // Function to update the selected medication image URL
  void _updateSelectedImageUrl(int index) {
    setState(() {
      selectedImageIndexNotifier.value = index;
      selectedImageUrl = imageUrls[index];
    });
  }

  // Function to handle date selection
  void _onDateSelected(DateTime newDate) {
    setState(() {
      _selectedDate = newDate;
    });
  }

  @override
  void initState() {
    // _initializeLocalNotifications();
    super.initState();
    if (widget.medicineToEdit != null) {
      // If editing an existing medicine, populate input fields
      _medicationNameController.text = widget.medicineToEdit!.name;
      _quantityController.text = widget.medicineToEdit!.amount;
      _doseController.text = widget.medicineToEdit!.dosage;
      _selectedDays = widget.medicineToEdit!.days;
      _reminderTimes = widget.medicineToEdit!.reminderTime;
      selectedImageUrl = widget.medicineToEdit!.image;
      // Trigger the bottom sheet to show after the build is complete
      WidgetsBinding.instance.addPostFrameCallback((_) {
        _showFormBottomSheet();
      });
    }
  }

  Future<List<Timestamp>> fetchReminderTimesFromFirestore() async {
    List<Timestamp> reminderTimes = [];

    try {
      // Reference to the 'medicine' collection in Firestore
      CollectionReference medicineCollection =
          FirebaseFirestore.instance.collection('medicine');

      // Fetch documents from Firestore
      QuerySnapshot querySnapshot = await medicineCollection.get();

      // Iterate through each document in the collection
      querySnapshot.docs.forEach((doc) {
        // Extract reminder times from the document data
        List<dynamic> reminderTimesData = doc['reminder_time'];

        // Convert dynamic data to Timestamp objects
        List<Timestamp> reminderTimesForDocument = reminderTimesData
            .map((timeData) => Timestamp.fromMillisecondsSinceEpoch(
                timeData.seconds * 1000)) // Convert seconds to milliseconds
            .toList();

        // Add reminder times to the list
        reminderTimes.addAll(reminderTimesForDocument);
      });
    } catch (e) {
      print('Error fetching reminder times: $e');
      // Return an empty list or handle the error as per your requirement
    }

    return reminderTimes;
  }

  // Function to build the medication input form as a bottom sheet
  Widget _buildMedicationFormSheet(BuildContext context) {
    return SizedBox(
      child: SingleChildScrollView(
        child: Padding(
          padding: const EdgeInsets.only(left: 20, right: 20, top: 40),
          child: Form(
            key: _formKey,
            child: Column(
              children: [
                // Header with back button and title
                Row(
                  children: [
                    IconButton(
                      icon: const Icon(
                        Icons.arrow_back_ios,
                        color: Color(0xffeb6081),
                        size: 20,
                      ),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                      constraints: const BoxConstraints(),
                    ),
                    Expanded(
                      child: Container(
                        alignment: Alignment.centerLeft,
                        child: const Text(
                          'Schedule your medicine intake',
                          style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 15,
                            color: Color(0xffeb6081),
                          ),
                        ),
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 12),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text('Medicine name'),
                    const SizedBox(
                      height: 8,
                    ),
                    // Input field for medication name
                    inputStyle(
                      prefixIcon: Icons.medication_rounded,
                      hintText: 'Ex. panadol',
                      controller: _medicationNameController,
                    )
                  ],
                ),
                const SizedBox(height: 12),
                Row(
                  children: [
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const Text('Quantity'),
                          const SizedBox(height: 8),
                          // Input field for medication quantity
                          inputStyle(
                              prefixIcon: Icons.medical_information,
                              hintText: '1 pil/tablet',
                              controller: _quantityController)
                        ],
                      ),
                    ),
                    const SizedBox(width: 20),
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const Text('Dosage'),
                          const SizedBox(
                            height: 8,
                          ),
                          // Input field for medication dosage
                          inputStyle(
                              prefixIcon: Icons.my_library_add_rounded,
                              hintText: '500mg/ml',
                              controller: _doseController),
                        ],
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 12),

                // MultiSelect widget for selecting days
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    MultiSelectBottomSheetField(
                      initialChildSize: 0.7,
                      maxChildSize: 0.95,
                      listType: MultiSelectListType.CHIP,
                      searchable: true,
                      buttonText: const Text('which days'), // Button text
                      title: const Text(
                          'select days to repeat'), // Title for the selection
                      items: _allDays
                          .map((day) => MultiSelectItem(day, day))
                          .toList(),
                      onConfirm: (values) {
                        // Callback when days are confirmed
                        setState(() {
                          _selectedDays = List<String>.from(values);
                        });
                      },
                      chipDisplay: MultiSelectChipDisplay(
                        onTap: (value) {
                          setState(() {
                            _selectedDays.remove(value);
                          });
                        },
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 12),

                // TimeInputWidget for selecting reminder times
                TimeInputWidget(
                  onTimeChanged: _updateReminderTime,
                ),

                const SizedBox(height: 12),

                // Medication image selection
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    const Text('Medicine type'), // Title for medication image
                    SizedBox(
                      height: 80,
                      child: ListView.builder(
                        scrollDirection: Axis.horizontal,
                        itemCount: imageUrls.length,
                        itemBuilder: (context, index) {
                          return GestureDetector(
                            onTap: () {
                              _updateSelectedImageUrl(
                                  index); // Update the selected image URL
                            },
                            child: ValueListenableBuilder<int>(
                              valueListenable: selectedImageIndexNotifier,
                              builder: (context, selectedImageIndex, child) {
                                return Container(
                                  width: 80,
                                  padding: const EdgeInsets.symmetric(
                                    horizontal: 8.0,
                                  ),
                                  decoration: BoxDecoration(
                                    border: Border.all(
                                      color: selectedImageIndex == index
                                          ? Colors
                                              .blue // Border color when selected
                                          : Colors
                                              .transparent, // No border when not selected
                                      width: 2.0, // Border width
                                    ),
                                  ),
                                  transform: Matrix4.identity()
                                    ..scale(0.8), // Scale down the image
                                  child: Column(
                                    children: [
                                      Expanded(
                                        child: Image.asset(imageUrls[index]),
                                      ),
                                    ],
                                  ),
                                );
                              },
                            ),
                          );
                        },
                      ),
                    ),
                  ],
                ),

                // Submit button for saving medication
                Padding(
                  padding: const EdgeInsets.only(top: 8.0, bottom: 8.0),
                  child: ElevatedButton(
                    style: ButtonStyle(
                      backgroundColor: MaterialStateProperty.resolveWith<Color>(
                        (states) => const Color(0xffeb6081), // Button color
                      ),
                      minimumSize: MaterialStateProperty.resolveWith<Size>(
                        (states) => Size(
                          MediaQuery.of(context).size.width * 0.95,
                          50.0,
                        ),
                      ),
                    ),
                    onPressed: () async {
                      if (_formKey.currentState!.validate()) {
                        // Create or update a Medicine object
                        Medicine medicine = Medicine(
                          id: widget.medicineToEdit
                              ?.id, // Use existing ID if in update mode
                          name: _medicationNameController.text,
                          dosage: _doseController.text,
                          image: selectedImageUrl,
                          days: _selectedDays,
                          reminderTime: _reminderTimes,
                          amount: _quantityController.text,
                        );

                        MedicationService medicationService =
                            MedicationService();

                        try {
                          if (widget.medicineToEdit == null) {
                            // Create mode: Save a new medicine
                            await medicationService.createMedicine(medicine);
                            if (kDebugMode) {
                              print('Medicine created successfully');
                            }
                          } else {
                            // Update mode: Update existing medicine
                            await medicationService.updateMedicine(medicine);
                            if (kDebugMode) {
                              print('Medicine updated successfully');
                            }
                          }

                          

                          // Clear input fields and state variables
                          _medicationNameController.clear();
                          _doseController.clear();
                          _quantityController.clear();
                          _selectedDays.clear();
                          _reminderTimes.clear();
                          selectedImageUrl = '';
                          // _scheduleMedicationNotifications;
                          Navigator.of(context).pop(); // Close the bottom sheet
                        } catch (e) {
                          if (kDebugMode) {
                            print('Error processing medicine: $e');
                          }
                        }
                      }
                    },
                    child: const Text(
                      'ADD', // Button text
                      style: TextStyle(
                          fontSize: 20,
                          fontWeight: FontWeight.normal,
                          color: Colors.white),
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    // Format the selected date for display
    String formattedDate =
        DateFormat('d MMMM').format(_selectedDate); // Use _selectedDate

    return Scaffold(
      body: SingleChildScrollView(
        child: Column(
          children: [
            // Display the DateSelector widget
            DateSelector(
              formattedDate: formattedDate,
              onDateSelected: _onDateSelected, // Set up the callback
            ),
            // Display the MedicationCard widget and pass the selected date
            MedicationCard(
                selectedDate:
                    _selectedDate), // Pass the selected date to MedicationCard
          ],
        ),
      ),
      bottomNavigationBar: Footer(
        onButtonPressed: _showFormBottomSheet, // Show the medication input form
      ),
    );
  }
}


New contributor

Waseem Thiab is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật