React Native Expoのローカル通知で毎月繰り返しは設定できない

React Native Expo で作ったスマホアプリで、毎月初めにローカル通知を送ろうとしたところ失敗しました。ソースコードとドキュメントを読んでみたところ、現状 React Native Expo のscheduleNotificationAsyncは「毎月」に対応していません。ここでは、調査した内容についてご説明します。

scheduleNotificationAsync で毎月のタイミングを指定するとエラーが発生

以下のように、情報の更新を促すローカル通知を毎月初めに繰り返しで出そうとしました。

await Notifications.scheduleNotificationAsync({
  content: {
    body: "ライフプラン・資産の実績を更新しましょう",
    badge: 1,
  },
  trigger: {
    day: 1,
    hour: 20,
    minute: 0,
    repeats: true,
  },
});

iOS では問題なかったのですが、Android のエミュレータで実行したらエラーが発生しました。

Failed to schedule the notification. Trigger of type: calendar is not supported on Android.

scheduleNotificationAsync のソースを読んでみる

node_modules/expo-notifications/build/scheduleNotificationAsync.d.tsを見ると、scheduleNotificationAsync はパラメータとして NotificationRequestInput を受け取ります。

export default function scheduleNotificationAsync(request: NotificationRequestInput): Promise<string>;

node_modules/expo-notifications/build/Notifications.types.d.tsを見ると、NotificationRequestInput のプロパティに NotificationTriggerInput があります。

export interface NotificationRequestInput {
  identifier?: string;
  content: NotificationContentInput;
  trigger: NotificationTriggerInput;
}

NotificationTriggerInput は union type で、その中に SchedulableNotificationTriggerInput があります。これは DateTriggerInput、TimeIntervalTriggerInput、DailyTriggerInput、WeeklyTriggerInput、CalendarTriggerInput の union type でした。あれ?MonthlyTriggerInput がありません。。。この中で使えそうなのは CalendarTriggerInput だけです。

export declare type SchedulableNotificationTriggerInput = DateTriggerInput | TimeIntervalTriggerInput | DailyTriggerInput | WeeklyTriggerInput | CalendarTriggerInput;
export declare type NotificationTriggerInput = null | ChannelAwareTriggerInput | SchedulableNotificationTriggerInput;

Expo のドキュメントを読んでみる

CalendarTriggerInput を Expo のドキュメントで調べてみたら、Note: This type of trigger is only available on iOS.と書かれていました。Android では使用できません。

Notifications - Expo Documentation

結論

無理やり毎週ローカル通知にします。DateTriggerInput で未来のすべての日付を指定すれば可能かもしれませんが、あまり気がすすみません。Android 版のリリース作業が終わったら、Expo の Issue として起票してみたいと思います。