How to trigger remider notifications dynamically at specific times in react native expo

23 Views Asked by At

Good day guys,

I am currently working on a medication remider app, where a user enters a medication, duration of usage and usage times of the medication, all these information are passed to the backend and retreived in the user object upon login.

Now the problem is how to handle the notifications locally. Is there a way to cache these medication data locally when user is logged in and trigger the reminder based on the usage times for each medication even if the app is in the background.

I am struggling with the logic of how to handle this, note that I have tested expo-notifications and notifee library in the project. The notifee library seems to be a better option, but I need the trigger be dynamic and based on the usage times. I would really appreciate any help I can get on this

So far, I have been able to sort the usage times of all medications into an array of object that display the next time for each medication to be taken as see below. This user has two medications

nextTimeArray = [
  Object {
    "id": "657bea7a24139ae6f4ee394f",
    "nextTime": 2023-12-31T15:00:00.232Z,
  },
  Object {
    "id": "6588ea40a148900e0403099c",
    "nextTime": 2023-12-31T12:00:00.232Z,
  },
]

I want that when it gets to 15:00 the notification for that medication is triggered locally

This is what the code looks like

const [filteredData, setFilteredData] = useState<any[]>([]);

const { data: medication, isLoading, isFetching, error, refetch, isSuccess } = useGetMedicationQuery({});

const medicationData = medication?.data || [];

useEffect(() => {

    const fetchData = async () => {
      try {
        await refetch();

        const today = new Date();

        if (medicationData) {

          let filteredDates = medicationData?.filter((item: { tillWhen: string | number | Date; }) => {
            const tillWhenDate = new Date(item.tillWhen);
            return tillWhenDate >= today;
          });

          setFilteredData(filteredDates);
        }

      } catch (error) {
        console.error('Error fetching medication:', error);
        // Handle error if needed
      }
    }
    fetchData();

  }, [medication])

  const convertToTime = (timeArray: string[] | undefined): Date[] | undefined => {
    return timeArray?.map((item) => {
      const [hours, minutes] = item.split(':');
      const time = new Date();
      time.setHours(Number(hours) + 1);
      time.setMinutes(Number(minutes));
      time.setSeconds(0);
      return time;
    });
  };

 const getNextTimeToTake = (entry: any): { _id: string, nextTime: Date | null | undefined } => {

    const currentDay = currentTime.toISOString().split('T')[0];

    if (entry.timeToTake && entry.timeToTake.length > 0) {
      const convertedTimes = convertToTime(entry.timeToTake);

      // Filter out times that are in the past and on previous days
      const futureTimes = convertedTimes?.filter(time => {
        const timeDay = time.toISOString().split('T')[0];
        return time > currentTime && timeDay === currentDay;
      });

      // Sort the future times in ascending order
      futureTimes?.sort((a: any, b: any) => a - b);

      // Get the next time or if there is none revert to first time in array
      const nextTime = futureTimes?.[0] || convertedTimes?.[0];

      return {
        _id: entry._id,
        nextTime
      };
    }

    // Return null if no timeToTake array is present
    return {
      _id: entry._id,
      nextTime: null
    };
  };

  const nextTimes = filteredData.map(getNextTimeToTake);

  const nextTimeArray = nextTimes.map(({ _id, nextTime }) => ({
    id: _id,
    nextTime: nextTime
  })); // This returns nextTimeArray above

filteredData= [
  Object {
    "__v": 0,
    "_id": "657bea7a24139ae6f4ee394f",
    "dailyIntakeCount": 0,
    "dosage": "1-1-1",
    "fromWhen": "2023-12-16T00:00:00.000Z",
    "name": "Vitamin C",
    "nextReminderTime": null,
    "tillWhen": "2024-01-07T00:00:00.000Z",
    "timeToTake": Array [
      "09:00",
      "15:00",
      "21:00",
    ],
    "timesDaily": 3,
  },
  Object {
    "__v": 0,
    "_id": "6588ea40a148900e0403099c",
    "dailyIntakeCount": 0,
    "dosage": "1",
    "fromWhen": "2023-12-25T00:00:00.000Z",
    "name": "Calcium ",
    "nextReminderTime": null,
    "tillWhen": "2024-01-08T00:00:00.000Z",
    "timeToTake": Array [
      "12:00",
    ],
    "timesDaily": 1,
  },
] //filteredData of active medications from the backend
0

There are 0 best solutions below