AWS（SNS, Cognito）を用いてAndroidアプリにプッシュ通知するまでの手順（サーバー編）

過去に自前のサーバーを用いてAndroidアプリにプッシュ通知の機能を構築したことはあるものの、サーバー部分をAWS（Amazon Web Services）に置き換えたい、という状況になったため、その手順をメモとして残しておきます。（2016年5月現在）

（ iOSアプリでの手順については [こちら](http://qiita.com/MJeeeey/items/c11cbebd542f06e68719) です。）

# 全体の流れ

前提条件としまして、対象のAndroidアプリは [Google Play Developer Console](https://play.google.com/apps/publish/) に登録できている状態にあるものとします。（アプリ公開の手順は既知とします。）

また、AWSのリージョンは「東京」を指定しているものとします。

大まかには、以下の流れで説明していきます。

1. Googleアカウント上の設定
1. AWS上の設定（SNS, Cognito）
1. AWS SDKの実装（Android Studio）
1. プッシュ通知の送信（AWS）


# GCM（Google Cloud Messaging）の設定

Android でプッシュ通知を実現するには、Google クラウド メッセージング（GCM）の設定が必要になります。

## Google Cloud Platform（GCP）へのプロジェクトの作成

1. [Google Cloud Platform](https://console.cloud.google.com/) にアクセスします。
1. 対象のAndroidアプリと連携するための、プロジェクトの作成を行います。

## Google API の設定

1. [Google API Console](https://console.developers.google.com/) にアクセスします。
1. GCP で作成したプロジェクトを選択します。
1. フレームから`概要`を選び、`Google Cloud Messaging`を有効にします。
1. フレームから`認証情報`を選び、`認証情報を作成`ボタンを押して、`サーバーキー`を作成します。（ここの作業は不要かも）

## Configuration ファイルの作成

1. ドキュメント [Set up a GCM Client App on Android](https://developers.google.com/cloud-messaging/android/client#get-config) にアクセスします。
1. `GET A CONFIGURATION FILE`ボタンを押すと、設定ファイルを作成するページに遷移します。
1. `App name`に「GCP で作成したプロジェクト」を選択し、`Android package name`に「対象のAndroidアプリのパッケージ名」を入力して、直下の`Choose and configure services`ボタンを押します。
1. `Server API Key`（サーバーAPIキー）と`Sender ID`（送信者 ID）が生成されていることを確認してください。（それぞれ後ほど使用します。）
1. 最下にある`Generate configuration files`ボタンを押します。
1. `Download google-services.json`ボタンが表示されているので、押すとConfiguration ファイル（google-services.json）が得られます。

Configuration ファイル（google-services.json）は、対象のAndroidプロジェクトの `app` フォルダ（Wear対応アプリの場合は `mobile` フォルダ）に移動してください。

**`Sender ID` は AWS SDKの実装内で使用します。**

## 送信者 ID の設定

1. [Google Play Developer Console](https://play.google.com/apps/publish/) にアクセスします。
1. 対象のAndroidアプリを選択します。
1. フレームで`サービスと API`を選択します。
1. `Google クラウド メッセージング（GCM）`で`送信者 ID をリンク`ボタンを押して、先ほどの手順で取得した`サーバーAPIキー`を入力してリンクしてください。先ほどの`送信者 ID`が表示されれば成功です。

Googleアカウント上の設定は以上です。


# SNS（Simple Notification Service）の設定（AWS）

ここからAWSに入ります。お持ちのAWSアカウントにログインして、サービス`SNS`を選択します。
プッシュ通知の送信部分の構築を行います。

## 1. Platform Applicationの作成

`Create Platform Application` を選択すると、入力フォーマットが表示されます。

1. `Application Name` にSNS上の識別子を記述する
1. `Push Notification Platform` で `Google Cloud Messaging (GCM)` を選択する
1. `API key` に GCMの設定（Configuration ファイルの作成）で取得した `Server API Key` を記述する
1. `Create Platform Application` ボタンを押す

これによって、以下のような Application ARN が得られます。

~~~
arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:app/GCM/[Application Name]
~~~

**`Application ARN` は AWS SDKの実装内で使用します。**

## 2. Topic の作成

Topic を作成すると、登録された複数のAndroid端末に対して一斉にプッシュ通知を送信することができます。

1. `Create Topic` を選択する
1. `Topic name` に Topic 上の識別子を記述する
1. `Create topic` ボタンを押す

これによって、以下のような Topic ARN が得られます。

~~~
arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:[Topic name]
~~~

**`Topic ARN` は AWS SDKの実装内で使用します。**

# Cognitoの設定（AWS）

サービス`Cognito`を選択します。

Cognito はユーザー識別、認証を行うサービスです。前のSNSと組み合わせることによって、モバイルへのプッシュ通知の構築を簡易に行うことができます。

## 1. Identity Poolの作成

`Getting started wizard`が開いたら、以下の手順を行います。

1. `Identity pool name` を入力する。
1. `Enable access to unauthenticated identities` をチェックする。
1. `Create Pool` ボタンを押す。

## 2. IAMロールの作成

上の設定に続き、IAMロールの作成を行います。
いったん、そのまま`許可`ボタンを押すとCognitoの設定は完了します。その後、サービス`IAM`を選択すれば編集することが可能です。

サービス`IAM`で編集する場合の手順です。

1. フレームから`ロール`を選択
2. リストから対象のロールを選択
3. `ポリシーの編集`を選択

`ポリシーの編集`は以下のように行います。

~~~json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "mobileanalytics:PutEvents",
                "cognito-sync:*"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "sns:CreatePlatformEndpoint",
                "sns:SetEndpointAttributes",
                "sns:Subscribe"
            ],
            "Resource": [
                "arn:aws:sns:ap-northeast-1:xxxxxxxxxxxx:*"
            ]
        }
    ]
}
~~~

## 3. Identity Pool Id の取得

`Identity pool` 画面右上の `Edit identity pool` をクリックすると遷移する画面にて確認できます。

~~~
ap-northeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
~~~

**`Identity Pool Id` は AWS SDKの実装内で使用します。**

# AWS SDKの実装（Android Studio）

こちらはこれだけで長くなりましたので、[こちらの記事](http://qiita.com/MJeeeey/items/3068f1e39ca074fa8e6e) にまとめました。

参考にしたサンプルコードを紹介しておきます。
[https://github.com/googlesamples/google-services/tree/master/android/gcm](https://github.com/googlesamples/google-services/tree/master/android/gcm)
[https://github.com/googlesamples/google-services/tree/master/android/gcm/app/src/main/java/gcm/play/android/samples/com/gcmquickstart](https://github.com/googlesamples/google-services/tree/master/android/gcm/app/src/main/java/gcm/play/android/samples/com/gcmquickstart)

# プッシュ通知の送信（AWS）

サービス`SNS`を選択します。

Topic に登録された Subscription の対象にある複数台の端末に対してプッシュ通知を送信します。

1. フレームから `Topics` を選択する
1. 対象の Topic にチェックを入れて、`Publish to topic` ボタンを押す（`Publish a message` 画面に遷移します）
1. `JSON message genarator` ボタンを押す（JSON生成ダイアログが表示されます）

`Message` に「プッシュ通知テスト」と入力しておきます。
`Target Platforms` は `Android` を選択します。

`Generate JSON` ボタンを押すと、前の画面に戻り、以下のように表示されていると思います。

~~~json
{
"default": "プッシュ通知テスト", 
"GCM": "{ \"data\": { \"message\": \"プッシュ通知テスト\" } }"
}
~~~

`Publish message` ボタンを押すとプッシュ通知が送信されます。登録した端末にプッシュ通知が届けば成功です。

# 最後に

GCM や AWS の仕様は随時変更になることが多いです。いろいろなWebの記事を参考にしましたが、手順や名称が変更してしまっているものがほとんどで、、それをきっかけに今回はまとめてみました。
内容の変更に気づいたときは修正していく予定です。