【expo-notification】公式ドキュメントのコード例で使用されている API を全てまとめてみた


# はじめに
[公式ドキュメント](https://docs.expo.dev/versions/latest/sdk/notifications/) の Usage で使用されている API をまとめてみました。
Expo 環境でモバイルアプリに通知機能を追加しようとしている方の助けになれば幸いです。

# 目次
- 使用されている API
  - [setNotificationHandler](#setnotificationhandler)
  - [setNotificationChannelAsync](#setnotificationchannelasync)
  - [getNotificationChannelsAsync](#getNotificationChannelsAsync)
  - [addNotificationReceivedListener](#addnotificationreceivedlistener)
  - [addNotificationResponseReceivedListener](#addnotificationresponsereceivedlistener)
  - [removeNotificationSubscription](#removeNotificationSubscription)
  - [scheduleNotificationAsync](#schedulenotificationasync)
  - [isDevice](#isdevice)
  - [getPermissionsAsync](#getpermissionsasync)
  - [requestPermissionsAsync](#requestpermissionsasync)
  - [getExpoPushTokenAsync](#getexpopushtokenasync)
- 公式ドキュメントで使用されている型
  - [Notification](#Notification)
  - [NotificationResponse](#NotificationResponse)
  - [EventSubscription](#EventSubscription)



# 使用されている API
## [setNotificationHandler](https://docs.expo.dev/versions/latest/sdk/notifications/#setnotificationhandlerhandler)

[型：NotificationHandler](https://docs.expo.dev/versions/latest/sdk/notifications/#notificationhandler)

主に、ユーザーへの通知の表示設定を行う。

この設定を行わないと、ユーザーに通知が表示されない。

```tsx
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true, // 通知の表示設定
    shouldPlaySound: false, // 通知のサウンド設定
    shouldSetBadge: false,  // 通知のバッジ設定
  }),
  // 以下はオプショナル
  // 通知が正常に処理された時に呼び出される関数
  handleSuccess:(notificationId: string) => void; 
  // 通知の処理が失敗した時に呼び出される関数
  handleError:(notificationId: string, error:NotificationHandlingError) => void;
});
```

## [setNotificationChannelAsync](https://docs.expo.dev/versions/latest/sdk/notifications/#setnotificationchannelasyncchannelid-channel)

Android 向けに通知チャネルを設定する。

ios のみの場合必要ない。

[AndroidImportance](https://docs.expo.dev/versions/latest/sdk/notifications/#androidimportance)

```tsx
  if (Platform.OS === 'android') {
    await Notifications.setNotificationChannelAsync(
    'myNotificationChannelId',  // channelId、アプリ内で一意
    // 通知チャネルの設定
    {
	    // 通知チャネル名
      name: string;
      // 通知の重要度。この設定によって通知方法が異なる。
      importance: AndroidImportance,
      // [通知が来てからバイブレーションが開始するまでの時間, バイブレーション時間, インターバル, バイブレーション時間]
      vibrationPattern: [0, 250, 250, 250],
      // デバイスの LED ライトの色を設定する。
      lightColor: '#FF231F7C',
    });
  }
```

<aside>

:::note warn
**channel** とは

Android で使用される概念。

Android では、channel を通じてユーザーに通知が送られる。
:::

</aside>

## getNotificationChannelsAsync

設定されている通知チャネルを全て取得する

## [addNotificationReceivedListener](https://docs.expo.dev/versions/latest/sdk/notifications/#addnotificationreceivedlistenerlistener)

アプリ動作中に通知を受けた際に呼び出されるリスナーを登録する

[Notification](#Notification)

```tsx
// 型
((event: Notification) => void) => EventSubscription;

// 例
  useEffect(() => {
	  // リスナーの登録
    const subscription = Notifications.addNotificationReceivedListener(notification => {
      console.log(notification);
    });
    
    // リスナーの削除
    return () => subscription.remove();
  }, []);
```

## [addNotificationResponseReceivedListener](https://docs.expo.dev/versions/latest/sdk/notifications/#addnotificationresponsereceivedlistenerlistener)

ユーザーが「通知をタップする」など、通知を操作するたびに呼び出されるリスナーを登録する

[NotificationResponse](#NotificationResponse)

```tsx
// 型
((event: NotificationResponse) => void) => EventSubscription;

// 例
useEffect(() => {
    const subscription = Notifications.addNotificationResponseReceivedListener(response => {
      const url = response.notification.request.content.data.url;
      Linking.openURL(url);
    });
    return () => subscription.remove();
  }, []);
```

## removeNotificationSubscription

登録したリスナーを削除する

## [scheduleNotificationAsync](https://docs.expo.dev/versions/latest/sdk/notifications/#schedulenotificationasyncrequest)

将来トリガーされる通知をスケジュールする。月毎、日毎など柔軟にスケジュールできる

あくまでも、通知をスケジュールするだけ

通知の「表示設定」に関しては `setNotificationHandler` で設定する

[content の詳しい情報](https://docs.expo.dev/versions/latest/sdk/notifications/#notificationcontent)

[SchedulableTriggerInputTypes](https://docs.expo.dev/versions/latest/sdk/notifications/#schedulabletriggerinputtypes)

[SchedulableTriggerInput](https://docs.expo.dev/versions/latest/sdk/notifications/#schedulablenotificationtriggerinput)

```tsx

// 引数の型
Notifications.scheduleNotificationAsync({
	// 通知の情報設定
  content: {
    body: string; // 通知メッセージ本体
    data: Record<string, any>; // 通知に紐づけられるデータ、ユーザーには表示されない。
    title: string | null;  // 通知タイトル
    subtitle:string | null // 通知サブタイトル
    sound: 'default' | 'defaultCritical' | 'custom' | null // 通知サウンド
  },
  
  // トリガー設定
  trigger: {
    type: SchedulableTriggerInputTypes; // スケジュールの種類。日毎、月毎など選択できる
    ...SchedulableNotificationTriggerInput; // スケジュールの種類（上記の type) によって形式が異なる
  },
});

// 例（20分ごとに繰り返しトリガーされる通知)
Notifications.scheduleNotificationAsync({
  content: {
    title: 'Remember to drink water!',
  },
  trigger: {
    type: SchedulableTriggerInputTypes.TIME_INTERVAL,
    seconds: 60 * 20,
    repeats: true,
  },
});
```

## [isDevice](https://docs.expo.dev/versions/latest/sdk/device/#deviceisdevice)(expo-device)

expo-device SDK の API

アプリの動作環境が実機の場合 `true` 

シミュレータやエミュレーターの場合 `false`

ウェブ上で動作している場合常に `true`

## [getPermissionsAsync](https://docs.expo.dev/versions/latest/sdk/notifications/#getpermissionsasync)

現在のアプリの通知に関するアクセス許可設定を取得できる。

戻り値は [NotificationPermissionsStatus](https://docs.expo.dev/versions/latest/sdk/notifications/#notificationpermissionsstatus)

```tsx
{
	// android
  importance: number,         // 通知の重要度
  interruptionFilter: number. // どの重要度の通知から許可するか
  
  // ios
	alertStyle: IosAlertStyle,  // 通知の表示スタイル NONE | BANNER(通知バナー) | ALERT(ポップアラート)
  allowsAlert: null | boolean, // 通知を表示できるか
  allowsAnnouncements: null | boolean, // 音声アナウンスなどの通知を許可するか
  allowsBadge: null | boolean, // バッジ表示を許可するか
  allowsCriticalAlerts: null | boolean, // 常に音が鳴る重要な通知を許可するか
  allowsDisplayInCarPlay: null | boolean, // CarPlay で通知を表示するかどうか
  allowsDisplayInNotificationCenter: null | boolean, // 通知センターに通知を表示するか
  allowsDisplayOnLockScreen: null | boolean, // ロック画面に通知を表示するか
  allowsPreviews: IosAllowsPreviews, // 通知のプレビューを許可するか
  allowsSound: null | boolean, // 通知サウンドを許可するか
  providesAppNotificationSettings: boolean, // アプリが通知設定画面を提供するか
  status: IosAuthorizationStatus // 通知の許可ステータス。"denied" | "granted" | "undetermined"
}
```

ドキュメントでは、 `status` が `granted` かどうかを判定するために使用されている。

```tsx
const { status: existingStatus } = await Notifications.getPermissionsAsync();
```

## [requestPermissionsAsync](https://docs.expo.dev/versions/latest/sdk/notifications/#requestpermissionsasyncpermissions)

ユーザーにアプリの通知権限を要求する API。

デフォルトで、アラートの表示、バッジの表示、サウンドの表示の許可を要求する。

android は通知の権限は all or nothing で細かい設定をアプリから変更することはできない。

この引数のオプションは ios のみ意味があると思われる。

```tsx
await Notifications.requestPermissionsAsync({
    ios: {
	    // 以下の三つはデフォルトで true
      allowAlert: boolean;
      allowBadge: boolean;
      allowSound: boolean;
      
      allowsCriticalAlerts: boolean; // 常に音が鳴る重要な通知を許可するか
		  allowsDisplayInCarPlay: boolean; // CarPlay で通知を表示するかどうか
		  allowProvisional: boolean; // 通知センターに継続的な通知を投稿する機能を許可するか
		  providesAppNotificationSettings: boolean; // アプリが通知設定画面を提供するか
    },
  });
```

## [getExpoPushTokenAsync](https://docs.expo.dev/versions/latest/sdk/notifications/#getexpopushtokenasyncoptions)

Expo のプッシュ通知サービスを使用してデバイスにプッシュ通知を送信するために使用できる Expo トークン。

Expo サーバーから通知を受け取る場合はこれを実行して保存しておく必要がある。

# 公式ドキュメントで使用されている型

## [Notification](https://docs.expo.dev/versions/latest/sdk/notifications/#notification)

```tsx
Notification: {
	date: number; // トリガーされた時刻
	request: NotificationRequest;
}

NotifionRequest: {
	content: NotificationContent;
	identifier: string; // 通知の ID 
	trigger: NotificationTrigger;
}

NotificationContent: {
  body: string; // 通知メッセージ本体
  data: Record<string, any>; // 通知に紐づけられるデータ、ユーザーには表示されない。
  title: string | null;  // 通知タイトル
  subtitle:string | null // 通知サブタイトル
  sound: 'default' | 'defaultCritical' | 'custom' | null // 通知サウンド
}

// 本来は、SchedulableNotificationTirggerInput 型以外もとりますが、割愛しています。
  // 詳細(https://docs.expo.dev/versions/latest/sdk/notifications/#notificationtrigger)
NotificationTrigger: {
  type: SchedulableTriggerInputTypes; // スケジュールの種類。日毎、月毎など選択できる
  ...SchedulableNotificationTriggerInput; // スケジュールの種類（上記の type) によって形式が異なる
}

SchedulableTriggerInputTypes: 'calender' | 'daily' | 'date' | 'monthly' | 'timeInterval' | 'weekly' | 'yearly'

```

## [NotificationResponse](https://docs.expo.dev/versions/latest/sdk/notifications/#notificationresponse)

```tsx
NotificationResponse: {
	actionIdentifier: string; // ユーザーの通知に対するアクションを識別するもの。
	notification: Notification;
	userText: string; // ユーザーが入力したテキスト
}
```

## EventSubscription

イベントリスナーを簡単に削除できるサブスクリプションオブジェクト。

主に、イベントリスナーを追加する API を返り値として返却される。

```tsx
EventSubscription: {
	remove: () => void;
}
```