Firestoreの簡易管理ツールをNuxt.jsでつくってみた

Firestore、とっても便利ですが、Firebaseのコンソールがイケてないので、
ローカルで動かせる簡易の簡易ツールを作ってみました。Nuxt.js製です。

Firebase Admin SDKを使ってるので、**秘密鍵を配置すればOK**。
**セキュリティルールの変更も不要**です。

動いているところはこんな感じ。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/e4d2f323-d2d7-39fb-e178-dc135f2e21f2.gif" width="680"/>


GitHubで公開してます。ただ書きなぐりなので、ソースはイケてないです。。
まだα版くらいなので、機能は限定的です。。

[memory-lovers/simple-firestore-admin: Simple Firestore Admin](https://github.com/memory-lovers/simple-firestore-admin)


### なんで作ったか

Firestoreを使った[Webサービス](https://tsundoku.site)を作ってみたところ、
ちょこっとしたDBの変更にもデータが多かったり、1ドキュメントのサイズが大きいと、
**Firebaseコンソールだと重い感じに**。。

いろいろ見ていると、Webサービスなどもあるのですが、
セキュリティールールを変えないといけないなど、設定がめんどくさいなと。。

なので、 **設定が少なくて、軽い管理ツールがほしい**、と思い、作ってみました。

### できること

とりあえず、いま自分が必要な機能だけなので、最小な感じ。

1. コレクションの検索: `collection().where().orderBy()`
2. ドキュメントの更新: `doc().update()`
3. ドキュメントの削除: `doc().delete()`


### 使い方

#### 1. インストール

インストールは、GitHubからクローンしてください。

```console
$ git clone git@github.com:memory-lovers/simple-firestore-admin.git
$ cd simple-firestore-admin
```

#### 2. セットアップ

##### 2-a. 秘密鍵の取得

Firebaseコンソールから秘密鍵を生成して配置してください。

左上の歯車から「プロジェクトの設定」をクリックし、

<img width="306" alt="スクリーンショット_2019-10-30_19_50_30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/8d3f5f8e-a641-3f6e-95e7-0889f86b9262.png">

「サービス アカウント」タブの下にある、「新しい秘密鍵を生成」をクリックすると、
秘密鍵のjsonファイルをダウンロードできます。

<img width="680" alt="スクリーンショット_2019-10-30_19_50_20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/8297e57c-12e6-b63e-c46b-3fbd0b8af8a9.png">

この例では、`./credential.json`としてます。

##### 2-b. 設定ファイル(.env)の作成と設定

`env_sample`という設定ファイルの雛形があるので、`.env`にコピーしてください。

```console
$ cp env_sample .env
```

コピーしたら、`.env`を開いて、配置した秘密鍵の相対パスを設定してください。

```diff
  # Copy this file with file name '.env'

  ## ex. CREDENTIAL_PATH=./credential.json
- CREDENTIAL_PATH=YOUR_CREDENTIAL_PATH
+ CREDENTIAL_PATH=./credential.json
```

これで設定はOK。

#### 3.起動

Nuxt.js製なので、こんな感じでビルドと起動をしてもらえればOK。

```console
# パッケージのインストール
$ npm install

# ビルド
$ npm run build

# 起動
$ npm run start
```

`http://localhost:3000`で起動するので、
ブラウザで操作できるようになります。

### 開発時のポイント: serverMiddlewareでfirebase-admin

開発時にハマったポイントとしては、
firebase-adminがNode.js上でしか使えなかったことです。。

当初はNuxtアプリから直接firebase-adminを呼ぼうとしていましたが、
**Node.js上でしか扱うことができない**ことをあとから知り。。

Expressなどからだと呼ぶことができるので、
Nuxtの[serverMiddleware](https://ja.nuxtjs.org/api/configuration-servermiddleware/#servermiddleware-%E3%83%97%E3%83%AD%E3%83%91%E3%83%86%E3%82%A3)を使って、
**APIサーバ的なものを内部で持たせるようにしてみました**。

serverMiddlewareの使い方はこんな感じ。

#### Express関連のコード

簡易化してますが、こんな感じのコードを、`server/index.ts`に配置

```typescript
import { Request, Response } from "express";
import * as firestore from "./modules/firestore";

import bodyParser from "body-parser";
import express from "express";

const app = express();

// setup body-parser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// select
app.post("/api/select", async (req: Request, res: Response) => {
  // firestore.collection("users").get()的な処理をする
  const result = await firestore.fetchSelect(req.body);

  res.send(result);
});

export default app;
```

#### nuxt.config.tsで設定

先ほど作成した`server/index.ts`をserverMiddlewareとして利用するように設定

```typescript
import { Configuration } from "@nuxt/types";

const config: Configuration = {
  serverMiddleware: ["~/server"],
};

export default config;
```

別にサーバを建てると、開発時にCORS対策でaxiosでproxyしないといけなかったりしますが、
serverMiddlewareを使うとそういった設定も不要に(*´ω｀*)


# おわりに

とりあえず、必要な部分だけを作っただけなので、
バグもイケてないところもまだまだありますが、よかったら遊んでみてもらえれば。

[memory-lovers/simple-firestore-admin: Simple Firestore Admin](https://github.com/memory-lovers/simple-firestore-admin)

Firestoreの管理画面作りたいな。。と思ったら、
こんな感じでserverMiddlewareを使うのが良さそうです(*´ω｀*)

## こんなのつくってます!!

冒頭で話していた開発しているWebサービスです！
だいぶデータも増えてきたので、こういう管理画面が欲しくなってきました。。

積読用の読書管理アプリ 『積読ハウマッチ』
[積読ハウマッチ](https://tsundoku.site)は、Nuxt.js+Firebaseで開発してます!

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="200"/>

もしよかったら、遊んでみてくださいヽ(=´▽`=)ﾉ

要望・感想・アドバイスなどあれば、
公式アカウント([@MemoryLoverz](https://twitter.com/MemoryLoverz))や開発者([@kira_puka](https://twitter.com/kira_puka))まで♪

# 参考にしたサイトさま
- [Nuxt+Expressのプロジェクト作成で良さそうなのは？ - Crieit](https://crieit.net/posts/Nuxt-Express)
- [Nuxt.js+Express.jsにTypeScriptを導入してみた - Qiita](https://qiita.com/sauzar18/items/6255877457b29c5f7421)
- [Nuxt.js v2.9にTypeScriptとExpress.jsを対応してみた - Qiita](https://qiita.com/sauzar18/items/d68c13f200b3bc671679)