Parse Server Unity SDKの使い方（プッシュ通知の使い方）

[ニフクラ mobile backendは3月末で終了します](https://mbaas.nifcloud.com/info/2023/12/post-171.html)。

ニフクラ mobile backendからの移行先として、お勧めしているのが[Parse Server](https://parseplatform.org/)です。設計思想が近く、変更するコード量が少なく済むのではないかと思います。

Parse ServerではUnity向けにSDKを提供していますが、ドキュメントは英語のみとなっています。そこで、各機能の使い方を解説します。今回はプッシュ通知の使い方を解説します。

## Unity SDKのインストール

Unity SDKのインストールは、NuGetを使う方法が紹介されています。Unity側であらかじめ設定が必要なので、下記記事を参考にNuGetの設定を追加します。

[Unity で NuGet パッケージを利用する \#Unity \- Qiita](https://qiita.com/akiojin/items/ac05392d97abb8797dcd)

そして、ParseのSDKは下記URLにて公開されています。

[NuGet Gallery \| parse 2\.0\.0\-develop\-1](https://www.nuget.org/packages/parse/absoluteLatest)

## 制限

Unity SDKは、Unity 5.2.x以降が必須です。

## link.xmlの作成

アセットフォルダの中に `link.xml` を作成し、下記内容を記述します。

```xml
<linker>
  <assembly fullname="UnityEngine">
    <type fullname="UnityEngine.iOS.NotificationServices" preserve="all"/>
    <type fullname="UnityEngine.iOS.RemoteNotification" preserve="all"/>
    <type fullname="UnityEngine.AndroidJavaClass" preserve="all"/>
    <type fullname="UnityEngine.AndroidJavaObject" preserve="all"/>
  </assembly>

  <assembly fullname="Parse.Unity">
    <namespace fullname="Parse" preserve="all"/>
    <namespace fullname="Parse.Internal" preserve="all"/>
  </assembly>
</linker>
```

## 初期化

まず `Parse` を読み込みます。

```csharp
using Parse;
```

初期化は2つの方法があります。 `2` の方法はマスターキーを指定もできるので、 C#としてデスクトップアプリやASP.NETの中で使う際に利用できる方法になります。

```csharp
// 1. キーを指定して初期化
ParseClient client = new ParseClient("Your Application ID", "The Parse Server Instance Host URI", "Your .NET Key");

// 2. 詳細を指定して初期化
ParseClient client = new ParseClient(new ServerConnectionData
{
    ApplicationID = "Your Application ID",
    ServerURI = "The Parse Server Instance Host URI",
    Key = "Your .NET Key", // This is unnecessary if a value for MasterKey is specified.
    MasterKey = "Your Master Key",
    Headers = new Dictionary<string, string>
    {
        ["X-Extra-Header"] = "Some Value"
    }
});
```

## プッシュ通知の設定

プッシュ通知を送信するためには、Parse Serverの初期化時に `push` キーの指定が必要です。

```js
push: {
	// iOS用の設定
	ios: {
		pfx: '/file/path/to/XXX.p12',
		passphrase: '', // p12/PFXのパスワード（オプション）
		bundleId: '',
		production: false
	},
	// Android用の設定
  android: {
    apiKey: '' // FCMのサーバーAPIキー
  },
}
```

## デバイストークンの取得

デバイストークンは、 `ParseInstallation.CurrentInstallation` からアクセスできます。

```csharp
var installation = ParseInstallation.CurrentInstallation
installation.Channels = new List<string> { "Giants" };
installation.SaveAsync();
```

保存されるデータは以下の通りです。ほとんどの項目が読み取り専用になっています。

| 項目             | 読み取り専用 | 説明                                                                                                                                                                                                                                                                                                  |
| ---------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| installationId   | ○            | Parseが使用するデバイスの一意のID                                                                                                                                                                                                                                                                     |
| deviceType       | ○            | デバイスのタイプ。"ios"、"osx"、"android"、"winrt"、"winphone"、"dotnet"、"embedded"のいずれか。Androidデバイスでは、このフィールドは"android"に設定されます                                                                                                                                          |
| pushType         | ○            | Parseが使用するプッシュ配信ネットワークを指定するためのフィールド。デバイスがFCM経由でプッシュを受信するように登録されている場合、このフィールドは"gcm"とマークされます。Google Playサービスが利用できない場合、このフィールドは空白になります                                                        |
| deviceToken      | ○            | FCMが登録IDを追跡するために使用するトークン。                                                                                                                                                                                                                                                         |
| appName          | ○            | このインストールが属するクライアントアプリケーションの表示名。この値は、デバイスからParseInstallationオブジェクトが保存されるたびに同期されます                                                                                                                                                       |
| appVersion       | ○            | このインストールが属するクライアントアプリケーションのバージョン文字列。この値は、デバイスからParseInstallationオブジェクトが保存されるたびに同期されます                                                                                                                                             |
| parseVersion     | ○            | このインストールが使用するParse SDKのバージョン。この値は、デバイスからParseInstallationオブジェクトが保存されるたびに同期されます                                                                                                                                                                    |
| timeZone         | ○            | ターゲットデバイスが現在位置しているタイムゾーン。この値は、デバイスからParseInstallationオブジェクトが保存されるたびに同期されます                                                                                                                                                                   |
| localeIdentifier | ○            | デバイスのロケール識別子。形式は[言語コード]-[国コード]。言語コードはISO 639-1で定義されている2文字の小文字のISO言語コード（例："en"）。国コードはISO 3166-1で定義されている2文字の大文字のISO国コード（例："US"）。この値は、デバイスからParseInstallationオブジェクトが保存されるたびに同期されます |
| badge            |              | iOSアプリのアイコンバッジの現在の値。サーバー上でこの値が変更されると、将来のバッジ増分プッシュ通知に使用されます                                                                                                                                                                                     |
| channelUris      | ○            | WindowsデバイスのためのMicrosoftが生成したプッシュURI                                                                                                                                                                                                                                                 |
| appIdentifier    | ○            | このインストールのクライアントアプリケーションの一意の識別子。このパラメータはAndroidではサポートされていません                                                                                                                                                                                       |

## 購読

購読は `ParseInstallation` オブジェクトにチャンネル名を追加することで行います。チャンネル名を指定して、 `SubscribeAsync` メソッドを使用します。

または `ParsePush.SubscribeAsync` メソッドを使用しても購読できます。

```csharp
var installation = ParseInstallation.CurrentInstallation;
installation.AddUniqueToList("channels", "Giants");
installation.SaveAsync();

// または
ParsePush.SubscribeAsync("Giants");
```

## 購読停止

購読停止は `ParseInstallation` オブジェクトからチャンネル名を削除することで行います。または、 `ParsePush` にてチャンネル名を指定して、 `UnsubscribeAsync` メソッドを使用します。

```csharp
var installation = ParseInstallation.CurrentInstallation;
installation.RemoveAllFromList("channels" new List<string> { "Giants" });
installation.SaveAsync();

// または
ParsePush.UnsubscribeAsync("Giants");
```

## 購読しているチャンネル一覧

購読しているチャンネル一覧は、 以下のようにして取得できます。

```csharp
var installation = ParseInstallation.CurrentInstallation
IEnumerable<string> subscribedChannels = installation.Channels;
```

## プッシュ通知の作成

プッシュ通知は、以下のようにして作成できます。なお、Parse Serverの設定として、アプリからのプッシュ通知作成を許可している必要があります。


```csharp
var push = new ParsePush();
push.Channels = new List<string> {"Giants"};
push.Alert = "The Giants just scored!";
push.SendAsync();
```

## デバイストークンの情報を更新する

デバイストークンのオブジェクトはParseObjectを継承しているので、通常のオブジェクトと同じように扱えます。

```csharp
var installation = ParseInstallation.CurrentInstallation;
installation["scores"] = true;
installation["gameResults"] = true;
installation["injuryReports"] = true;
installation.SaveAsync();
```

## ユーザー情報をデバイストークンに紐付ける

デバイストークンにユーザー情報を紐付ける場合には、ログインユーザー情報を `put` メソッドで設定します。

```csharp
var installation = ParseInstallation.CurrentInstallation;
installation["user"] = ParseUser.CurrentUser;
installation.SaveAsync();
```

## クエリを使ったプッシュ通知

`ParseInstallation.Query` を使うことで、絞り込み条件を伴ったプッシュ通知を作成できます。

```csharp
var push = new ParsePush();
push.Query = ParseInstallation.Query
             .WhereEqualTo("injuryReports", true);
push.Alert = "Willie Hayes injured by own pop fly.";
push.SendAsync();
```

## まとめ

Parse Serverのプッシュ通知の実装はとても簡単です。NCMBと比べてもほとんど変わらないでしょう。また、プッシュ通知は管理画面でビジュアル的に作成できるので、それも便利です。

データの管理方法などはParse ServerとNCMBで似ています。他のmBaaSと比べると、全体の修正量はそこまで多くないと思われます。載せ替え先として検討に挙げてください。

[Unity Developers Guide \| Parse](https://docs.parseplatform.org/unity/guide/#push-notifications)