Nuxt.js+FirebaseでAIメーカーのAPIを使ったサンプルを作った
Tags: nuxt, vue, firebase, cloudfunctions
Published: 2018-10-01 02:24:47

---
title: Nuxt.js+FirebaseでAIメーカーのAPIを使ったサンプルを作った
published: true
description: 
tags: nuxt,vue,firebase,cloudfunctions
canonical_url: https://crieit.net/posts/Nuxt-js-Firebase-AI-API
---

先日[AIメーカー](https://aimaker.io)にてAPIが公開されたので、試しにAPIを使ったWebアプリケーションを作ってみました。今回は画像をアップしなくても、ボタンを押すだけで自分のTwitterアイコンで判定できるようにしてみました。

ちなみに、現在はAIメーカー本家にもTwitterアイコンで判定できる機能が実装されています。個人開発のサービスでAPIまで公開されているものは珍しいので遊んでみたくなりました。

## もくじ

* [環境構築](#環境構築)
* [開発環境の準備](#開発環境の準備)
* [Nowにデプロイ ← デモURLはこちら](#Nowにデプロイ)
* [細かい処理の流れ](#細かい処理の流れ)

![ai maker api tester.png](https://thepracticaldev.s3.amazonaws.com/i/902wc92uhvaux6cb5xpe.png)



## 構築環境

* Nuxt.js
* Firebase Authentication
* Google Cloud Functions
* Now

という感じのサーバーレス構成です。GitHubから取得してNowにデプロイするまでをざっと説明していきます。

## 開発環境の準備

ソースはGitHubにあげてあります。基本的な流れはそちらのREADMEにも書いてあります。

[dala00/ai-maker-api-sample](https://github.com/dala00/ai-maker-api-sample)

### 依存関係のインストール

```bash
yarn
```

### AIメーカーのapikeyを取得

AIメーカーにログインし、他の方が作成されているAIの詳細画面にあるAPIのパラメータを見ると自分のapikeyが表示されていますので、そちらをメモっておきます。

### Firebaseの環境設定

予めFirebaseに登録し、Firebase Consoleにてプロジェクトを作成しておきます。

![Firebaseのウェブアプリ設定](https://thepracticaldev.s3.amazonaws.com/i/wqagpdn2ezyb5oeeej16.png)

プロジェクトの設定画面を開くとこのボタンがありますので、クリックして設定情報を取得します。

`env.sample.js`というファイルがありますので、それを`env.development.js`、`env.production.js`としてコピーし、各ファイルの中身を上記で取得した設定で埋めておきます（CLOUD_FUNCTIONS_BASE_URL以外）。

#### Authenticationの設定

Twitterログインを使用していますので、Firebase ConsoleのAuthenticationのログイン方法設定でTwitterを有効にしておきます。（[Twitter側でのアプリケーションの設定](https://developer.twitter.com/)も必要です）

#### Cloud Functionsの設定

firebase-toolsをPCにインストールし、シェルでfunctions関連の操作を行えるようにします。それを使ってfirebaseにログインし、functionsを初期化します。

```bash
npm install -g firebase-tools
firebase login
firebase init functions
```

##### アプリケーションの設定

functions内で使う値を設定しておきます。許可するURLとAIメーカーのapikeyの設定です。

```bash
firebase functions:config:set cors.origin=http://localhost:3000
firebase functions:config:set ai_maker.apikey=apikeygotfromaimaker
```

##### functionsをデプロイ

```bash
firebase deploy --only functions
```

これでfunctionsの管理画面を見るとURLが表示されているので、前述のCLOUD_FUNCTIONS_BASE_URLに値を入れておきます。imageClassificationの前のスラッシュまで入れます。

### ローカルで起動

問題なければこれでローカル環境で動くようになっていると思います。開発モードで起動し、`http://localhost:3000`にアクセスします。

```bash
yarn run dev
```

## Nowにデプロイ

```bash
now
```

これでデプロイできます。デプロイ時にURLが表示されますので、あとはFirebase Authenticationの許可ホスト名にそのホスト名を設定しておきます。また、cors.originも本番のURLを指定します。

デプロイするたびにホスト名が変わってしまいますが、その度に毎回設定するのは非常に面倒なので、何度もデプロイする場合は`now alias`を利用するとよいでしょう。一つ固定のホスト名を指定しておき、デプロイ時に発行されるURLにそれを関連付ける事ができます。

下記は実際にデプロイしたデモです。（しばらく誰もアクセスしていないと一度止まるようですので、その場合にアクセスすると表示されるまでに少々時間がかかります）

[https://ai-maker-api-tester.now.sh](https://ai-maker-api-tester.now.sh)

あと細かい調整をしていないのですが、Twitterログインから戻ってきた直後は少しだけログイン前の画面の表示になっています。待っていればログイン状態になり判定が行われます。（その他も変な挙動があるかもしれません。SPAだとgetRedirectResultのコールバックとか何度も呼ばれてるかも）

## 細かい処理の流れ

細かい処理の流れを簡単に説明しておきます。

### データ

データは data/ai.js の中に配列で定義されています。現在AIの一覧取得APIは無いようですので、必要な分だけここで定義しておきます。

### Twitterアイコンをfunctionsに送信

apikeyは隠したいため、functionsのconfigに設定し、function内でAIメーカーのAPIを実行します。そのため、Nuxt側からはAIのidとTwitterアイコンURLだけをfunctionに送信します。

```javascript
      const params = {
        id: this.ai.id,
        image: this.$store.state.user.photoURL
      };
      axios
        .post(
          process.env.CLOUD_FUNCTIONS_BASE_URL + "imageClassification",
          params
        )
        .then(response => {
          this.labels = response.data.labels;
        })
        .catch(error => {
        });
```

### function内でAPIを実行

Firebaseで取得できる画像URLは小さい画像のもので、これだといい感じに判定されないため大きい画像のURLに変換します。まずそのURLの画像を取得しておき、それをAPIに送信します。画像ファイル名も送信する必要があります。

```javascript
    const form = new FormData();
    const image = await getImage(req.body.image.replace("normal.", "400x400."));
    form.append("id", req.body.id);
    form.append("apikey", functions.config().ai_maker.apikey);
    form.append("file", image, getFileName(req.body.image));
    form.submit(
      "https://aimaker.io/image/classification/api",
      (err, apiResponse) => {
        if (err) {
          console.error(err);
          res.status(500).json({ error: true });
          return;
        }

        chunks = [];
        apiResponse
          .on("data", chunk => {
            chunks.push(chunk);
          })
          .on("end", () => {
            const body = Buffer.concat(chunks).toString();
            const labels = JSON.parse(body);
            console.info(labels);
            res.json(labels);
          });
      }
    );
```

ここで返却した値はNuxt側でそのまま表示され、完了です。（実際にはスコア順に並び替えています）

## まとめ

以上のように、Nuxt.js + Firebase + Cloud Functionsを利用したサーバーレス構成でのアプリケーション作成で遊んでみました。Nuxt.jsなのでSPA、SSR、PWAも可能ですし、FirebaseとCloud Functionsでサーバーを持つ必要もないので非常に気が楽ですね。

今回はデプロイにNowを使いましたが、GAE、Herokuでも同様のことが無料枠で可能です。

完成後再度環境構築までは試していないので、もし環境構築でつまづく場合があれば連絡いただければ確認します。