FlutterにOneSignalを導入する

Push通知やアプリ内メッセージを簡易に導入し、分析できるツールに[OneSignal](https://onesignal.com/)があります。本記事ではFlutterにOneSignalを導入し無料でプッシュ通知を送信する方法を紹介します。
また、プッシュ通知のユースケースとして、イベントを契機に送信するという事が多いと思います。こちらについて簡単な例を紹介します。


# OneSignalの良いところ

- プッシュ通知を送るだけなら無料プランでも可能
    - プッシュ通知送信数はプランに関わらず無制限
    - 管理画面上からイベントをトリガーに送信も可能
- 導入が簡単でドキュメントが充実している


# 導入方法

Flutterで導入する方法は以下の公式ドキュメントの通りに行うと良いです。

https://documentation.onesignal.com/docs/flutter-sdk-setup

注意点を挙げておきます。

- `NotificationServiceExtension`の導入もされていますが、リッチプッシュ等の機能を使う際に必要なものです。必ずしも実装する必要はないです。


# イベントを契機にプッシュ通知送信
## 概要

ここではイベントを契機にプッシュ通知を送るという機能を作成する方法を紹介します。
手順は以下になります。各機能は後述します。

1. イベント対象のデータを`Data Tags`を使用してユーザーに登録する
1. 1で登録した`Data Tags`を用いて`Segments`を設定する
1. 2で登録した`Segments`を配信対象として`Automated Messages`を設定する。


### [Data Tags](https://documentation.onesignal.com/docs/add-user-data-tags)

Data Tagsを使う事でユーザーに対してkey-vakue形式でデータを紐づける事ができます。
例えば購入商品数をユーザーに持たせるとして`purchase_count: 10`といった形です。この`Data Tags`は後述する`Segments`を作成する際の条件に使用できます。

### [Segments](https://documentation.onesignal.com/docs/segmentation)

`Segments`はユーザーが持つ属性やデータに基づいてセグメンテーションできる機能です。例えば「初回起動からx時間後」や、「Data Tagsのkey xxxの値がyyyである」といったセグメンテーションが可能です。

### [Automated Messages](https://documentation.onesignal.com/docs/automated-messages)

ユーザーが`Segments`に入った事をトリガーにして自動でプッシュ通知やメールを送信する機能です。

## 実装、設定例


以下初回起動から2日目で購入数というパラメータが0のユーザーに対してプッシュ通知を送る際の例を示します。

### Flutter側

- `OneSignal`の設定
- 購入数の同期

を行います。

#### `OneSignal`の設定

以下の実装を任意の場所で行います。基本的には起動時すぐに呼ばれる箇所に実装するのが良いと思います。

```dart

// OneSignalにユーザー登録
OneSignal.shared.setAppId("YOUR_ONESIGNAL_APP_ID");

// プッシュ通知を開いた際のコールバック。必要であれば実装する
OneSignal.shared.setNotificationOpenedHandler((OSNotificationOpenedResult result) {
  // Will be called whenever a notification is opened/button pressed.
});
```

#### 購入数の同期

`Data Tags`を使用し、購入数として`purchase_count`というkeyで購入数を登録します。
購入数の変化がある際に以下のようにOneSignalと同期します。

```dart
  void updatePurchaseCount() {
    final purchaseCount = // 現在の購入数を取得;
    OneSignal.shared.sendTag("purchase_count", purchaseCount);
  }
```

`purchase_count`を同期したユーザーのプロフィールを確認し、以下のように同期されていれば完了です。


![スクリーンショット 2023-05-25 15.46.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3296911/27f7857a-9158-bda9-6a43-011205bd9243.png)


### OneSignal管理画面

1. 初回起動から2日目で購入数が0という`Segments`を作成します


    ![スクリーンショット 2023-05-25 15.25.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3296911/865804fd-c2c7-abc6-637d-529534029773.png)

1. 1で作成した`Segments`を使用して`Automated Messages`を作成します 
`Automated Messages`の対象`Segments`に上記で作成したものを設定します。これで設定は完了です。
条件を満たしたユーザーに対して自動でプッシュ通知が送られるようになります。

![スクリーンショット 2023-05-25 16.26.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3296911/71161f96-dd08-6af5-f1d2-29f7d6e12087.png)


# その他

## プッシュ通知が送信されるまでのラグについて

`Automated Messages`について、無料プランの場合はユーザーが`Segments`に入ってからPush送信まで数時間程のラグが発生する場合があると記載があります。
https://documentation.onesignal.com/docs/automated-messages#step-3-delivery-schedule
筆者が試した所、記載の通りラグが発生する事が時折ありました。
即時Push通知を送る事が必要な場合は有料プランを使用する必要があります。


## 課金対象ユーザーについて

課金対象となるユーザーはユーザー一覧の中でSubscribedがチェックされているユーザーのみとなります。
`Permission Not Granted`や`Apns Delegate Never Fired`のユーザーは対象外となります。
またアプリをアンインストールすると自動で購読者から外されます。

<img width="320" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3296911/0c87d48a-b837-c72e-5c25-57611b0d52d5.png">


## [External User Id](https://documentation.onesignal.com/docs/flutter-sdk-setup#set-external-user-id)について

各サービス毎にユーザーのidを管理していると思います。これをOneSignalに連携させる事で
また、何か問題があった際にどのユーザーなのかという事が特定しやすくなります。
OneSignalでは[`External User Id`](https://documentation.onesignal.com/docs/flutter-sdk-setup#set-external-user-id)というユーザーに対して独自の識別子を設定できる機能があります。これを使用すると良いです。

## [Journeys](https://documentation.onesignal.com/docs/journeys)について

ユーザーの行動に応じて連続したアクションを設定できる`Journeys`という機能もあります。
これは無料プランでは使用できないので本記事では紹介しておりません。