Amplify x Ionic使ってみた

こんにちは。株式会社キネカの[AkiraTakeguchi](https://twitter.com/AkiraTakeguchi)です。

この記事は、[Ionic Advent Calendar 2018](https://qiita.com/advent-calendar/2018/ionicframework "Ionic Advent Calendar 2018")の3日目の記事です。

本記事は先日のre:Inventで発表されたAmplify x Ionicを使ってみて、「おー！すげー！」となってみることを目標とします。この記事がIonicを初めて使用する方の手助けになると良いなーと。

[Ionic Japan Users' Group](https://ionic-jp.connpass.com/)が主催した[HTML5 APP CONFERENCE 2018](https://html5app-conf.connpass.com/event/87730/)のなかでAmazon Web Service（発表の登録に合わせています）さんが[フロントエンドでクラウドをいい感じに使う](https://speakerdeck.com/keisuke69/using-cloud-from-frontend)という発表をされていました。私はそこで初めてAmplifyに触れたのですが、その時の衝撃がとても強く印象に残っています。特に、技術を学びたての人や、webアプリは初めて、という方にはとても入りやすいかと思います。
（と、やる前は思っていたのですが、そこそこハマりポイントありでした...本記事が参考になれば幸いです。）

本記事は下記3つのサイトの手順を複合的に参照して進めていきます。

https://aws-amplify.github.io/docs/js/start#step-4-integrate-aws-resources
https://aws-amplify.github.io/docs/js/authentication
https://aws-amplify.github.io/docs/js/tutorials/building-ionic-4-apps/#part-3-adding-authorization

それぞれがまだ未完成のようで、、、それぞれ抜けている手順があり、適宜参照箇所を変えていく必要がありました。

#### 本記事の開発環境

* Ionic 4.5.0
* Node.js 10.14.1
* npm 6.4.1
* OS macOS High Sierra
* aws-amplify 1.1.10
* aws-amplify-angular 2.0.13

# Getting Started

初めに、Ionicのプロジェクトを作ります。（npmがインストールされていない方は、node.jsをインストールすることから始めましょう。）

```
$ npm install -g ionic
$ ionic start myAmplifyProject tabs --type=angular
$ cd myAmplifyProject
```

2行目`ionic start`の時に

```
? Install the free Ionic Appflow SDK and connect your app? (Y/n)
```

と聞かれますが、これはYesでもNoでもどちらでもOKです。Appflowの詳細はこちらhttps://ionicframework.com/appflow
今回はNoで進行します。

続いて、Amplifyをインストールします。

```
$ npm install --save aws-amplify
$ npm install --save aws-amplify-angular
$ npm install --save ionic-angular
```

2行目はAmplifyが提供するAngularのモジュールです。Amazon Cognito User Poolや, Amazon PinPoint, Amazon S3, AWS AppSync, Amazon API Gatewayへのリクエスト処理などを簡単に実装することができます。キモですね。
3行目はionicが提供するモジュールです。どちらも入れておきましょう。

次にAWSのバックエンドをセットアップします。
※[こちら](https://aws-amplify.github.io/docs/js/start?platform=ionic)のGetting Startedを見ていると、次のコマンドが`amplify init`となっていますが、この時点では`amplify`は見つかりません。`amplify-cli`のインストール手順が抜けています。私が記事を書いている時点では[こちらのサイト](https://aws-amplify.github.io/docs/js/ionic)が正しい手順です。

```
$ npm install -g @aws-amplify/cli
$ amplify init
```

セットアップ時に複数個の選択肢があります。それぞれ本記事で選択したものに矢印をつけておきます。

```
? Choose your default editor: (Use arrow keys)
  Sublime Text
  Visual Studio Code
  Atom Editor
  IDEA 14 CE
❯ Vim (via Terminal, Mac OS only)
  Emacs (via Terminal, Mac OS only)
  None
```

```
? Choose the type of app that you're building (Use arrow keys)
  android
  ios
❯ javascript
```

Ionicの記事なのでIonicを選択しましょう（笑）

```
? What javascript framework are you using (Use arrow keys)
  react
  react-native
  angular
❯ ionic
  vue
  none
```

ここの4つはEnterでOKです。

```
? Source Directory Path:  (src)
? Distribution Directory Path: www
? Build Command:  (npm run-script build)
? Start Command: (ionic serve)
```

new userをセットアップしてみましょう。Yesを押すとブラウザが開き、awsアカウントへのログインが求められます。ログインしたらCLIに戻りEnterを押します。

```
AWS access credentials can not be detected.
? Setup new user (Y/n)
```

すると、regionの選択がでてくるので、東京（ap-northeast-1）を選択しておきましょう。

```
Specify the AWS Region
? region:
  us-west-2
  eu-west-1
  eu-central-1
❯ ap-northeast-1
  ap-southeast-1
  ap-southeast-2
  ap-south-1
(Move up and down to reveal more choices)
```

user名を聞かれます。私はamplify-ionic-tutorialとしました。

```
Specify the username of the new IAM user:
? user name:  (amplify-RUx8H)
```

ブラウザが開き、IAMのユーザー作成画面に飛びます。

![screencapture-console-aws-amazon-iam-home-2018-12-03-00_32_21.png](https://qiita-image-store.s3.amazonaws.com/0/45193/ec39f00f-4b8a-7b24-40d4-ebce827fbf1a.png)

特に何も考えず、右下にある青いボタンを5回ほど押し続けるとユーザーの作成に成功します。（説明をはしょります。）
ここで、最後の画面内にあるアクセスキーIDとシークレットアクセスキーをメモっておきます。

![スクリーンショット 2018-12-03 0.37.43.png](https://qiita-image-store.s3.amazonaws.com/0/45193/02d8c4eb-92f5-248a-a79e-5973562b47a0.png)

この画面が出てきたら、アクセスキーIDとシークレットアクセスキーをメモって、閉じるを押してCLIに戻り、Enterを押しましょう。するとアクセスキーIDとシークレットアクセスキーの入力を求められます。メモるの忘れて閉じちゃったよーって人は[AWS IAM](https://console.aws.amazon.com/iam/home AWS)の画面を開いて作成したユーザーの認証情報を確認すれば載ってます。

```
Enter the access key of the newly created user:
? accessKeyId:  (<YOUR_ACCESS_KEY_ID>)
? secretAccessKey:  (<YOUR_SECRET_ACCESS_KEY>)
```

[名前付きプロファイル](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-multiple-profiles.html)の設定を求められます。

```
This would update/create the AWS Profile in your local machine
? Profile Name: Akira Takeguchi
```

この辺りはお任せします。入力例のみ載せておきます。

```
Successfully set up the new user.

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-multiple-profiles.html

? Do you want to use an AWS profile? (Y/n)
? Please choose the profile you want to use
❯ Akira Takeguchi
```

以上が終了すると、`amplify init`が完了します。

# Amplify APIを使ってみる。

Amplifyの破壊力を知るために認証APIを実際に使用してみましょう。

## Authentication

メインはAmazon Cognito User Poolsを使用します。

```
$ amplify add auth

Using service: Cognito, provided by: awscloudformation
 The current configured provider is Amazon Cognito.
 Do you want to use the default authentication and security configuration? (Use arrow keys)
❯ Yes, use the default configuration.
  No, I will set up my own configuration.
  I want to learn more.

$ amplify push
? Are you sure you want to continue? 

```

`amplify push`が完了すると、必要なIAMの設定やCognito上でのユーザープールの作成、AWS Lambda、CloudFormationがよしなにセッティングされます。これら4つのサービスが何をやっているのかわからなくても、とりあえずAWSのサービスを使ったユーザー認証基盤ができてしまいます。すごい。

## 実装

### 下準備

この時点で
`src/aws-exports.js`
というファイルが存在していると思いますが、このファイルを
`aws_exports.ts`
にリネームする必要がるようです。拡張性がtsに変わってますね。そのために、`package.json`を編集します。

```
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
```

となっているところを

```
  "scripts": {
    "ng": "ng",
    "start": "[ -f src/aws-exports.js ] && mv src/aws-exports.js src/aws-exports.ts || ng serve; ng serve",	
    "build": "[ -f src/aws-exports.js ] && mv src/aws-exports.js src/aws-exports.ts || ng build --prod; ng build --prod"	
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
```

このように修正しましょう。変わったのは`start`と`build`の部分です。これで意識せずにリネームしてくれます。どうやら`npm start`からの`ng serve`をする前提のようですね。ですが、IonicにはIonic DevAppという本当に素晴らしいツールがあります。これを利用するためにも、`ng serve`ではなく、`ionic serve`を使用するように`start`コマンドを編集しておきましょう。

```
  "scripts": {
    "ng": "ng",
    "start": "[ -f src/aws-exports.js ] && mv src/aws-exports.js src/aws-exports.ts || ionic serve; ionic serve",	
    "build": "[ -f src/aws-exports.js ] && mv src/aws-exports.js src/aws-exports.ts || ng build --prod; ng build --prod"	
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e"
  },
```

これで`npm start`を打つと`ionic serve`で立ち上がり、Ionic DevAppから参照可能になります。Ionic DevAppは実機でのデザイン確認や、Ionic Nativeの一部機能をそのまま試せたりと、Ionicの開発では欠かせないものです。是非使用してみてください。

次に`src/main.ts`を編集します。以下の3行を追記しましょう。Amplifyの設定をIonicに読み込みます。

```ts

import Amplify from 'aws-amplify';
import amplify from './aws-exports';
Amplify.configure(amplify);
```

次に`src/app/app.module.ts`を編集します。必要なモジュールをimportしています。

```ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';

import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { AmplifyAngularModule, AmplifyService } from 'aws-amplify-angular';

@NgModule({
  declarations: [AppComponent],
  entryComponents: [],
  imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule, AmplifyAngularModule],
  providers: [
    StatusBar,
    SplashScreen,
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    AmplifyService
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}
```

こんな感じです。`AmplifyAngularModule`と`AmplifyService`を読み込ませるようにします。これでAmplify APIを使用する準備が整いました。

### npm startがエラーになる場合の対処

ここで一旦`npm start`を起動したらエラーになります。
下記の二つを行うことで無事に消えました。

src/tsconfig.app.jsonを編集する

```json
{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "types": ["node"]
  },
  "exclude": [
    "test.ts",
    "**/*.spec.ts"
  ]
}
```
`"types": []`を`"types": ["node"]`に修正しています。

`src/index.html`を編集する。

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Ionic App</title>

    <base href="/" />

    <meta
      name="viewport"
      content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
    />
    <meta name="format-detection" content="telephone=no" />
    <meta name="msapplication-tap-highlight" content="no" />

    <link rel="icon" type="image/png" href="assets/icon/favicon.png" />

    <!-- add to homescreen for ios -->
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="black" />

    <script>
      if (global === undefined) {
        var global = window;
      }
    </script>

  </head>
  <body>
    <app-root></app-root>
  </body>
</html>
```
`<script>...</script>`のところが追記されています。

上記編集が終了したら`npm start`とコマンドを打って`http://localhost:4200/`を開いてみましょう。Ionicで見慣れてたtabsプロジェクトが表示されるはずです。

![screencapture-localhost-4200-tabs-home-home-2018-12-03-01_41_19.png](https://qiita-image-store.s3.amazonaws.com/0/45193/4599206c-869c-8428-69a8-1f9b81e72411.png)

この辺りは、後々修正されることを祈っています。。。

### Authの追加

>To use Authenticator, just add the amplify-authenticator directive in your .html view
> `<amplify-authenticator framework="Ionic"></amplify-authenticator>`

？？？？？！！！！！！！！！！
そんな、、、この1行をhtmlに含めれば終わりだと。。。？？？
やってみます。今回は`src/app/home/home.page.html`に追記してみましょう。

```html
<ion-content padding>
  <amplify-authenticator framework="Ionic"></amplify-authenticator>
</ion-content>
```

追記して、saveするとlive reloadされます。エラーです。
`'amplify-authenticator' is not a known element:`と言われてエラーになります。

「`amplify-authenticator`なんて知らないよ」と怒られているので、教えてあげましょう。

`home.module.ts`を編集する必要があります。

```ts
import { IonicModule } from '@ionic/angular';
import { RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HomePage } from './home.page';
import { AmplifyAngularModule, AmplifyIonicModule, AmplifyService } from 'aws-amplify-angular' // 追記


@NgModule({
  imports: [
    IonicModule,
    CommonModule,
    FormsModule,
    AmplifyAngularModule, // 追記
    AmplifyIonicModule,   // 追記
    RouterModule.forChild([{ path: '', component: HomePage }])
  ],
  declarations: [HomePage]
})
export class HomePageModule {}
```

3行追記します。これでsaveすると、エラーが無くなりますね。そしてなんと！素晴らしいUIが表示されました。

![screencapture-localhost-8100-tabs-home-home-2018-12-03-02_33_21.png](https://qiita-image-store.s3.amazonaws.com/0/45193/8e52a0f2-ca0b-308e-d08b-8ec839573182.png)

`Create account`からユーザーを作成してみましょう。

![screencapture-localhost-8100-tabs-home-home-2018-12-03-02_34_02.png](https://qiita-image-store.s3.amazonaws.com/0/45193/264cb51c-70c6-0598-d226-16b7745796d9.png)

ここで注意です。Ionic DevApp上で確認すると、Alertが表示されず、Sign Upをした時に何がエラーになっているのか不明です。。。
ブラウザでテストすることを推奨します。この辺り、`amplify-authenticator`がまだいけてないのかな。。。
特にPasswordのバリデーションが強力です。
それと、emailは実際に存在するemailにしましょう。なんと次の画面でemailへ送られる認証コードの入力が求められます。

![screencapture-localhost-8100-tabs-home-home-2018-12-03-02_35_02.png](https://qiita-image-store.s3.amazonaws.com/0/45193/9a879ec6-b00d-8b77-c6c9-bfe16a503067.png)

`Confirm Code`を押すと、ログイン画面に遷移します。Sign inすると

![screencapture-localhost-8100-tabs-home-home-2018-12-03-02_35_19.png](https://qiita-image-store.s3.amazonaws.com/0/45193/427f0f1a-0f21-9bae-ddec-9cc9931fef10.png)

このように表示されます。ユーザーの作成、ログインが完了です。メール認証までついていて素晴らしいですね。

# まとめ

Amplify x Ionicでのプロジェクト作成から、ユーザー認証の導入までを解説いたしました。いくつかハマりどころがあるのと、この手順に沿って実行すれば安心、と呼べるドキュメントが揃っていないところがリリースしたばかりのプロダクト感がありました。おそらくこの記事もすぐに古いものとなり、手順が更新されていくことになると思います。また、手順としてまだまだ省略できそうなものが存在するので、今後のリリースに期待しています。
とはいえ、認証まわりだけ試してみたものの、`amplify-authenticator`はかなり偉大ですね。まさかメール認証までしっかりと付いているとは驚きました。ここまでをAWSのサービスを意識せずに勝手に必要なものを揃えてくれるのは嬉しいですね。Storageの使用やAPIの作成など、まだまだ試してみたい機能が盛りだくさんです。

皆さんもAWS Amplifyを使用して良きIonicライフを送ってください〜。

私がCTOを勤める[株式会社キネカ](https://www.wantedly.com/companies/company_1138164)ではIonicアプリを3つ運用しており、2年以上の運用実績があります。Ionicに関する質問は下記のTwitterアカウントのDMまで投げてもらえれば、なんでも答えます。ご気軽にどうぞ！！
https://twitter.com/AkiraTakeguchi

採用も全力で行なっております！Ionicを使って仕事したい方は是非お声がけください。

## Appendix

こちらの手順がとてもわかりやすくまとめられています。本記事の中でも複数回エラーで戸惑いましたが、こちらのサイトを参考にさせていただき解決いたしました。合わせてお読みいただくと、より深く理解が進むかと思います。
https://playfulit.net/articles/try-using-aws-amplify-with-angular