【プッシュ通知】Y Combinatorも投資するOneSignalがFirebaseより便利で素晴らしかった

## TL; DR
Y Combinatorが投資している、急成長中[^1]のプッシュ通知ASP OneSignalを試してみました。
Firebaseと同じく無料ながら、Parseのような柔軟性（A/Bテスト、ユーザープロパティ、自動配信など）を持っています。
Firebaseが抱える「プロパティに上限があるが削除できない」、「他ASPからトークンをインポートできない」等の問題もなく、初めてParseを試したときのように感動しました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/119686/c701d07f-3844-ee8c-d5f6-b14c742aed3f.png" width=50%>

## Firebaseの問題
ポストParse時代の代表格は、なんといってもGoogle I/O 2016でバージョンアップが発表されたFirebase。
認知度、Googleというバックボーンともに圧倒的な存在ですが、使ってみると意外に「？」と思うことがいくつかありました。詳しくは[こちら](http://qiita.com/ko2ic/items/3d25d41971636a28cc1c)に書かれているような点です。
いくつか挙げるとすれば↓の点が気になりました。

* 登録可能なユーザープロパティ数は自動収集されるもの（年齢層、性別、端末情報など）を除き最大25個まで。 削除できない
* セグメントが更新されない
* データの反映が遅い
* 他ASPからトークンをインポートできない

## OneSignalとは？
* Y Combinatorが投資している、急成長中[^1]のプッシュ通知ASP
* Uber, Line, Zynga, ProductHuntなどを含む22万ユーザー以上に利用されてきた実績あり
* iOS, Android, Web Push, Unityなどに対応。近日中にAmazon Alexaに対応するとか
* 価格は**無料**。ネット広告と同じく、利用データを収益源にしている模様[^2]。サポート付きの有料プランもあり
* Parseと同じく、プッシュ配信サービス + ユーザーDBを持つ。ユーザーDBが見やすい
* ユーザープロパティは無限に登録可能
* デリバリーサービスはRustで書かれている
* （2017年8月21日追記）配信性能は5,000プッシュ/秒。現在、処理速度UPに向けアプデ中[^3]

## Firebaseとの特徴・機能比較
Firebaseとの違いをざっとまとめてみました。
間違いがあれば修正依頼を送ってください。

| | OneSignal | Firebase |
|--------|--------|--------|
| 価格|無料|無料|
| 日本語|☓|○| 
| API|○|○| 
|トークンインポート機能|○|☓（これないと厳しい）|
|リアルタイム開封率|○|△（リアルタイムではないかな？）|
|スケジュール配信|○|○|
|端末のタイムゾーンに対応|○|○|
|定期配信|○|△（API利用）|
|セグメント配信|○|△（セグメント更新されない問題）|
|A/Bテスト|○|△（セグメント利用）|
|ユーザー一覧|○|☓|
|ユーザープロパティ|○（無限）|△（独自は最大25個。削除できない）|
|アグリゲートデータ|☓|○（全体を俯瞰できるのが強み）|
|多言語配信|○|△（セグメント利用）|
|iOS10(メディア配信、サブタイトル）|○（専用フォーム）|○（カスタムデータ指定）|
|メッセージテンプレート|○|☓|
|絵文字入力ヘルパー|○|☓|
|端末をテスターとして登録|○|☓（本番・開発でアプリ分ける必要あり）|

---

## 使ってみた（ユーザーデータ編）
ここからはiOSで試した内容です。

### 実験1. ユーザー登録
登録といってもSDK導入後、アプリを起動するとユーザーが自動的に登録されます。
Parseのようにユーザーごとの登録状況が把握でき、わかりやすいです。

![console.png](https://qiita-image-store.s3.amazonaws.com/0/119686/ae1f866b-b5cb-2830-1f34-32d6e81736d9.png "console.png")


### 実験2. ユーザープロパティ（Tags）登録
Firebaseのユーザープロパティ = OneSignalのData Tags(Tags)です。
Tagsには、KeyValueデータを登録します。
Firebaseのユーザープロパティは独自で25個登録できますが、Tagsは無限に登録できます。
とはいえ、ユーザーが300万以上いる場合、20個以上のtagを設定するのは通知配信に影響が出るため非推奨とされています[^4]。

ここではテスト目的で、100個のtagを登録してみました。


```swift
// 100個のtagを追加
var tags: [String: Int] = [:]
for i in (1...100) {
    tags["tag" + String(i)] = i
}
OneSignal.sendTags(tags)
```

#### 結果
tagsに100個のtagが登録されました。瞬時に更新されるのは見ていて気持ちが良いです！
FirebaseだとDebugViewで見たり、まずコンソール側でプロパティを登録し、数時間経った後にセグメントを切る必要があります。

![OneSignal.png](https://qiita-image-store.s3.amazonaws.com/0/119686/0fc6d11d-90e4-35e0-cfe9-d0136f59685f.png "OneSignal.png")


### 実験3. Tagを更新
tagsを一部だけ更新してみます。
試しに`tag1`だけ変更してみます。

```swift
OneSignal.sendTag("tag1", value: "foobar")
```

#### 結果
tags同様、瞬時に変更されました。
![tags.png](https://qiita-image-store.s3.amazonaws.com/0/119686/19b92808-4158-fcf8-8c64-61524f915b41.png "tags.png")


## 使ってみた（プッシュ編）
### セグメント自動プッシュ
セグメント条件を満たしたユーザーに自動的にプッシュを送信する機能です。
例えば、無料ユーザーが課金ユーザーになった際などに使えます。

#### 1. Segment登録
試しに課金ユーザーのSegmentを作ってみました。
課金ユーザーの条件は'subscription'tagの値が1の場合として設定します。
![segment.png](https://qiita-image-store.s3.amazonaws.com/0/119686/fda9c313-27fa-4dd5-df13-0a80ab1c58ae.png "segment.png")


#### 2. Template登録
課金ユーザー向けにメッセージテンプレートを登録します。
title, messageに加えて、iOS10向けにSubtitleフォームがあるのはありがたいです。
絵文字ヘルパー（矢印）も便利でした！
![kakin.png](https://qiita-image-store.s3.amazonaws.com/0/119686/714523ca-c69d-49b1-546a-5ceefd57fe4b.png "kakin.png")


#### 3. 課金ユーザーにする
ユーザーを課金ユーザーに変身させます。
```
OneSignal.sendTags(["subscription": 1])
```

#### 4. 自動メッセージ登録
Template, Segmentを使って自動メッセージを登録すると、課金ユーザー向けプッシュが瞬時に送信されてきました。
この登録タイミング以外は、30分毎にセグメント条件に合うユーザーがいるかチェックし、プッシュを送信するようです。
なお、デフォでは自動メッセージは1度しかユーザーに送られない設定になっています。

![automated.png](https://qiita-image-store.s3.amazonaws.com/0/119686/9e72c251-c771-1845-2c2f-7cf8eed25628.png "automated.png")

[^1]: 2016年4月時点では[3万強ユーザー](https://onesignal.com/blog/onesignal-updates/)、2017/08/19現在、[22万強ユーザー](https://onesignal.com)。
[^2]: https://techcrunch.com/2017/08/15/onesignal-series-a/
[^3]: 直接問い合わせ、2017-08-21付で回答を得た
[^4]: https://documentation.onesignal.com/v3.0/docs/add-user-data-tags