Android Local Notifications not working on API 33

I am running Ionic/React with Local Notifications v5.0.2. They are not firing on Android running 33. The documentation on local notifications is not good and I am not sure what to do. In the official docs it says this:

Android 13 requires a permission check in order to send notifications. You are required to call checkPermissions() and requestPermissions() accordingly.

Does that mean both checkPermissions and request permissions has to be called in the file to fire off a notification??

Here is my code that is not firing the notification. When I check the pending status, all my notifications load in with the correct date and time, yet don’t fire…

import { useEffect } from 'react';
import { LocalNotifications } from '@capacitor/local-notifications';
import { Preferences } from '@capacitor/preferences';
import { isPlatform } from '@ionic/react';

import {
  getJuly1stAt12pm,
  getSept23rdAt12pm,
  getSept30thAt8am,
  get27thDayAt12pm,
} from '../util/getNextNotificationDates';

const useLocalNotifications = () => {
  const STORAGE_KEY = '2023-05-09';

  const scheduleMonthlyNotification = async () => {
    const pending = await LocalNotifications.getPending();
    const now = new Date();
    const nextMonth27th = get27thDayAt12pm(now);

    if (!pending.notifications.some((notification) => notification.id === 4)) {
      if (isPlatform('android')) {
        await LocalNotifications.schedule({
          notifications: [
            {
              title: 'Monthly Receipt Reminder ⛽️',
              body: `Don't forget to upload your fuel receipts!`,
              id: 4,
              schedule: {
                at: nextMonth27th,
                allowWhileIdle: true,
                count: 1,
              },
            },
          ],
        });
      } else {
        await LocalNotifications.schedule({
          notifications: [
            {
              title: 'Monthly Receipt Reminder ⛽️',
              body: `Don't forget to upload your fuel receipts!`,
              id: 4,
              schedule: {
                allowWhileIdle: true,
                on: {
                  day: 27,
                  hour: 12,
                  minute: 0,
                },
              },
            },
          ],
        });
      }
    }
  };

  const scheduleFilingOpen = async () => {
    const now = new Date();
    const scheduleOpen = getJuly1stAt12pm(now);
    const pending = await LocalNotifications.getPending();

    if (!pending.notifications.some((notification) => notification.id === 1)) {
      if (isPlatform('android')) {
        await LocalNotifications.schedule({
          notifications: [
            {
              title: `Claim Your Tax Refund Now! 💰`,
              body: 'You can now file for your fuel refund! Press the file return button to get started.',
              id: 1,
              schedule: {
                at: scheduleOpen,
                allowWhileIdle: true,
                count: 1,
              },
            },
          ],
        });
      } else {
        await LocalNotifications.schedule({
          notifications: [
            {
              title: `Claim Your Tax Refund Now! 💰`,
              body: 'You can now file for your fuel refund! Press the file return button to get started.',
              id: 1,
              schedule: {
                on: {
                  month: 7,
                  day: 1,
                  hour: 12,
                  minute: 0,
                },
              },
            },
          ],
        });
      }
    }
  };

  const scheduleWeekUntilClose = async () => {
    const now = new Date();
    const scheduleWeekUntilCloseDate = getSept23rdAt12pm(now);
    const pending = await LocalNotifications.getPending();

    if (!pending.notifications.some((notification) => notification.id === 2)) {
      if (isPlatform('android')) {
        await LocalNotifications.schedule({
          notifications: [
            {
              title: 'One Week Left To File! ⏳',
              body: 'You have one week left to file for your fuel refund!',
              id: 2,
              schedule: {
                at: scheduleWeekUntilCloseDate,
                allowWhileIdle: true,
                count: 1,
              },
            },
          ],
        });
      } else {
        await LocalNotifications.schedule({
          notifications: [
            {
              title: 'One Week Left To File! ⏳',
              body: 'You have one week left to file for your fuel refund!',
              id: 2,
              schedule: {
                on: {
                  month: 9,
                  day: 23,
                  hour: 12,
                  minute: 0,
                },
              },
            },
          ],
        });
      }
    }
  };

  const scheduleFilingClose = async () => {
    const now = new Date();
    const scheduleClose = getSept30thAt8am(now);
    const pending = await LocalNotifications.getPending();

    if (!pending.notifications.some((notification) => notification.id === 3)) {
      if (isPlatform('android')) {
        await LocalNotifications.schedule({
          notifications: [
            {
              title: 'One Day Left To File! 🚨⏰',
              body: 'Today is the last day to file for your fuel refund!',
              id: 3,
              schedule: {
                at: scheduleClose,
                allowWhileIdle: true,
                count: 1,
              },
            },
          ],
        });
      } else {
        await LocalNotifications.schedule({
          notifications: [
            {
              title: 'One Day Left To File! 🚨⏰',
              body: 'Today is the last day to file for your fuel refund!',
              id: 3,
              schedule: {
                on: {
                  month: 9,
                  day: 30,
                  hour: 8,
                  minute: 0,
                },
              },
            },
          ],
        });
      }
    }
  };

  useEffect(() => {
    (async () => {
      try {
        const permissions = await LocalNotifications.requestPermissions();

        if (permissions.display === 'granted' && isPlatform('capacitor')) {
          const { value } = await Preferences.get({
            key: 'notificationsSetUp',
          });

          if (!value) {
            await scheduleFilingOpen();
            await scheduleWeekUntilClose();
            await scheduleFilingClose();
            await scheduleMonthlyNotification();
            await Preferences.set({
              key: 'notificationsSetUp',
              value: STORAGE_KEY,
            });
          }

          if (value && value !== STORAGE_KEY) {
            await LocalNotifications.cancel({
              notifications: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }],
            });
            await scheduleFilingOpen();
            await scheduleWeekUntilClose();
            await scheduleFilingClose();
            await scheduleMonthlyNotification();
            await Preferences.set({
              key: 'notificationsSetUp',
              value: STORAGE_KEY,
            });
          }

          const pending = await LocalNotifications.getPending();

          if (
            !pending.notifications.some((notification) => notification.id === 1)
          ) {
            await scheduleFilingOpen();
          }
          if (
            !pending.notifications.some((notification) => notification.id === 2)
          ) {
            await scheduleWeekUntilClose();
          }
          if (
            !pending.notifications.some((notification) => notification.id === 3)
          ) {
            await scheduleFilingClose();
          }
          if (
            !pending.notifications.some((notification) => notification.id === 4)
          ) {
            await scheduleMonthlyNotification();
          }

          const pendingTest = await LocalNotifications.getPending();
          console.log('pendingTest', pendingTest);

          LocalNotifications.addListener(
            'localNotificationReceived',
            async (notification) => {
              switch (notification.id) {
                case 1:
                  await scheduleFilingOpen();
                  break;
                case 2:
                  await scheduleWeekUntilClose();
                  break;
                case 3:
                  await scheduleFilingClose();
                  break;
                case 4:
                  scheduleMonthlyNotification();
                  break;
                default:
                  console.log(
                    'Unknown notification ID received:',
                    notification.id
                  );
              }
            }
          );
        } else {
          console.log('User denied local notifications');
        }
      } catch (e) {
        console.log('e', e);
      }
    })();
  }, []);

  return null;
};

export default useLocalNotifications;

1 Like

Hi!
Did you found any solution? I’m not able to fire any notifications scheduled on Android… i tried to create a channel, asign it to the schedule options, without chanel and using the default one, … i’m not taking any solution for android. Ios working properly, but Android…

1 Like