Skip to content

How to schedule a “birthday”” notification in React Native Expo Notifications?

I want to schedule a notification for the user’s birthday. Right now I am trying to do that when he registers and he gives his date of birth. When he click “Register” I add the data to the database and also call this function to schedule his birthday using the date data that he provided:

export const scheduleUserBirthday = async(date) => {
  var dob = new Date(date)
  const birthdayDay = dob.getDay();
  const birthdayMonth = dob.getMonth();
  const myBirthdayThisYear = new Date(new Date().getFullYear(), birthdayMonth, birthdayDay).setHours(23, 59, 59);
  
  const addToYear = myBirthdayThisYear > Date.now() ? 0 : 1;
  const oneDay = 24*60 * 60 * 1000;
  const secondDate = new Date(new Date().getFullYear() + addToYear, birthdayMonth, birthdayDay);
  const firstDate = new Date();
  const days = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime()) / (oneDay)));

  
  await Notifications.scheduleNotificationAsync({
    content: {
      title: Happy Birthday,
      body: 'Have a wonderfull day'
    },
    trigger: { 
      day:days
      repeats: true,
    },
  });
}

However this gives me this error:

[Unhandled promise rejection: Error: Failed to schedule the notification. Trigger of type: calendar is not supported on Android.]

I noticed that it only works if hour and minute parameter is given, so I tried to add the next notification in hours but got the same result.

Does the trigger object only accepts this format: hour < 24 and minutes < 60?

I am a little bit lost… (Also would like to set scheduled notifications for 3 months in the future)

Answer

By the looks of it, when you try to use this format of trigger it is using Calendar API to schedule a notification.

This feature seems to be only available on iOS as the docs say.

What you could do instead is try to force the use of YearlyTrigger like so:

import * as Notifications from "expo-notifications";
import { Platform } from "react-native";

export const scheduleUserBirthday = async (date) => {
  const dob = new Date(date);

  const day = dob.getDay();
  const month = dob.getMonth();

  if (Platform.OS === "android") {
    await Notifications.setNotificationChannelAsync("birthday-reminder", {
      name: "Birthday reminder",
      description: "Remind user about his birthday!",
      importance: Notifications.AndroidImportance.HIGH,
      sound: "default",
    });
  }

  await Notifications.scheduleNotificationAsync({
    content: {
      title: "Happy Birthday",
      body: "Have a wonderfully day",
      sound: "default",
    },
    trigger: {
      channelId: "birthday-reminder",
      day: day,
      month: month,
      hour: 0,
      minute: 0,
      repeats: true,
    },
  });
};

This will also help you with creating a recurring notification for each year, so you don’t have to worry about that part.

One additional thing I added is setNotificationChannelAsync. I think it’s sort of mandatory to supply a notification channel on android.

Although Expo created one default channel for you, creating a specific channel for birthday reminders has its benefits. It would allow the user to toggle on/off that specific notification type from system application settings