Firebaseにユーザーをimportできるようになった

たまたまgithubの[firebase-tools(firebase-cli)](https://github.com/firebase/firebase-tools)みてたら、表題の通り`auth:import`コマンドを使うことでユーザーのimportが可能になってることを知りました！
日本語はまだみたいですが、ドキュメントもできてます。
https://firebase.google.com/docs/cli/auth-import

この機能追加によって、既存のユーザーデータをFirebaseに簡単に取り込むことが可能そうです。
さっそくためしてみました！[^1]

## firebase-toolsをインストール
firebase-toolsはnpmに登録されてるので、適当にディレクトリ掘って準備します。

```bash:console
$ mkdir firebase-migration && cd firebase-migration
$ npm init # 適当に情報入れます
$ npm install --save-dev firebase-tools # global installでもいいですが、あんまり好きじゃないので
```
今回の私みたいにglobal installしない場合は`package.json`に下記を書いておきましょう。

```json:package.json
  "scripts": {
     "firebase": "firebase"
  }
```
これで `npm run firebase [command]` でfirebase-toolsのコマンドが叩ける用になります。
global installした方は、以降にでてくる`npm run firebase`は単に`firebase`と置き換えてお読みください。

npm的な作業はこれで終わりです。

## firebase-toolsの初期設定
続いてfirebase-tools用の初期設定です。まずはfirebaseにログインしましょう。

```bash:console
$ npm run firebase login

? Allow Firebase to collect anonymous CLI usage information? (Y/n)
```
ここで`y`を選択すると、ブラウザが開きFirebase CLIが認証を求めてきます。
これを許可したあとにコンソールにもどり、

```bash:console
✔  Success! Logged in as sample@mail.com
```
と表示されてたらログイン成功です。

次に、初期化です。

```bash:console
$ npm run firebase init

     🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥     🔥🔥🔥     🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥
     🔥🔥        🔥🔥  🔥🔥     🔥🔥 🔥🔥       🔥🔥     🔥🔥  🔥🔥   🔥🔥  🔥🔥       🔥🔥
     🔥🔥🔥🔥🔥🔥    🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥   🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥
     🔥🔥        🔥🔥  🔥🔥    🔥🔥  🔥🔥       🔥🔥     🔥🔥 🔥🔥     🔥🔥       🔥🔥 🔥🔥
     🔥🔥       🔥🔥🔥🔥 🔥🔥     🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥     🔥🔥  🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥

You're about to initialize a Firebase project in this directory:

  /home/otakki/firebase-migration

? What Firebase CLI features do you want to setup for this folder? (Press <space> to select)
❯◉ Database: Deploy Firebase Realtime Database Rules
 ◉ Hosting: Configure and deploy Firebase Hosting sites
```
こんな感じの画面が出てきます。
めっちゃずれてますが、🔥の絵文字で「FIREBASE」って書いてます。燃えすぎ。
今回の作業では`Hosting`だけチェックを入れましょう。
移行だけで言えばどちらも必要有りませんが、`Hosting`を使って検証を行います。

```bash:console
=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.

? What Firebase project do you want to associate as default? (Use arrow keys)
❯ [don't setup a default project]
  My Project (<project-id>)
  [create a new project]
```
すでにプロジェクトがある場合は、`My Project(つけたプロジェクト名)`が表示されてるはずですので、それを選びます。
ない場合は`[create a new project]`を選択してつくりましょう。

プロジェクトを選択し終えたらhostingの設定が始まりますが、これはいったん全部デフォルトで良いでしょう。

以上で初期化も終了です。
ここまでの作業が終わると、下記のようなファイルが生成されていると思います。

```bash:console
$ tree -a -L 1
.
├── .firebaserc
├── firebase.json
├── node_modules
├── public
└── package.json
```
それぞれ

* `.firebaserc`: プロジェクト情報
* `firebase.json`: hostingの情報が書いてある。
* `public`: hosting用ディレクトリ。あとで消す。

が記述されてます。こうなっていれば初期設定は終わりです。

## データをインポートする
ドキュメントにも記述がありますが、インポートにはCSVかJSONファイルを用いることができます。今回はJSONを使うことにしました。
こんなかんじ。

```json:users.json
{
  "users": [
    {
      "localId": "1",
      "email": null,
      "emailVerified": null,
      "passwordHash": null,
      "salt": null,
      "displayName": "テストユーザー",
      "photoUrl": null,
      "providerUserInfo": [
        {
          "providerId": "twitter.com",
          "rawId": "xxxxxxxxxxxx",
          "email":  null,
          "displayName": "テストユーザー",
          "photoUrl": null
        }
      ]
    }
  ]
}
```
プロバイダはtwitterのみを想定してます。
`providerUserInfo[0].rawId`にはツイッターのID(not `screen name`)を記述しましょう。
`localId`だけ必須です。今回は試しなのでだいたい`null`にしてます。
`localId`は、Firebase上でユニークになるようにしてください。この値がFirebase上での`uid`となり、もし同じ値を設定してしまうと情報は完全に上書きになります。
RDSのデータを移行するのであれば、基本的にはプライマリーキーを指定してやれば大丈夫だと思います。

早速取り込んでみましょう。下記のようにコマンドを実行します。

```bash:console
$ firebase auth:import ./users.json --hash-algo=HMAC_SHA256 --hash-key=hogehoge
```
必須のオプションは`hash-algo`だけですが、そこで設定するアルゴリズムによって追加でオプションが必要になります。詳細は[ドキュメント](https://firebase.google.com/docs/cli/auth-import#syntax)にて。
今回はユーザーパスワードを持ってない前提なのでどれでもいいのですが、ひとまず`HMAC_SHA256`を選びました。

```bash:console
Processing ./users.json (439 bytes)
Starting importing 1 account(s).
✔  Imported successfully.
```
実行後、このように表示されていれば成功です。

## 確認してみる
`https://console.firebase.google.com/project/<project-id>/authentication/users`
にアクセスしてみると、下記のようにユーザーが登録されているのが確認できると思います。
<img width="943" alt="スクリーンショット 2016-11-10 18.40.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/63367/9260c86c-bd64-f5c1-5f5e-01c140953abf.png">
ちゃんとプロバイダがTwitterアイコンになってますね。

## ちゃんとログインできるのかも確認する
念のため、実際にクライアントからもログインしてみましょう。
今回は確認に[quickstart-js](https://github.com/firebase/quickstart-js)を使いました。

```bash:console
$ git clone https://github.com/firebase/quickstart-js
# デフォルトのエントリポイントを削除
$ rm -fr public
# 認証系サンプルをpublicにもってくる
$ mv quickstart-js/auth public
# 残りは今回入らないので削除
$ rm -fr quickstart-js
# localhost:5000にserve
$ npm run firebase serve
```
すごい雑な設定の仕方ですが、これで http://localhost:5000/ にアクセスできるようになるはず。
<img width="1276" alt="スクリーンショット 2016-11-15 13.27.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/63367/cc18e791-3fd7-7b73-b705-4ebeaa98c19c.png">
アクセスしてみて、上記のような画面になっていれば成功です。

今回はTwitterしかProvidorとして登録してないので、「Twitter Sign In using Popup」で確認することにします。
が、ここまでの手順だけではまだ確認はできませんので、そのために少しだけ作業を。

`public/twitter-popup.html`を開くと、30行目あたりに

```html
  <!-- Firebase -->
  <!-- ***********************************************************************************************************************
       * TODO(DEVELOPER): Paste the initialization snippet from: Firebase Console > Overview > Add Firebase to your web app. *
       *********************************************************************************************************************** -->
```
と書いてます。この手順通りにとってきた`<script>`要素をこの位置にコピペします。
その後、あらためて http://localhost:5000/twitter-popup.html にアクセスすると認証が可能になります。

認証した結果がこちら
<img width="728" alt="スクリーンショット 2016-11-15 12.35.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/63367/2bacd195-1642-084d-756e-655aaa19c266.png">
いろいろと隠してますが、`uid` が`"1"`となっているのが確認できると思います。
成功してますね。

## 最後に
作業が終わったら、念のため

```bash:console
npm run firebase logout
```
しておきましょう。



## まとめ
これまでは、ユーザーデータをFirebaseに移行しようとするには、各ユーザーにFirebaseを通じて認証してもらい、
そこから得られる各プロバイダのID等と元のデータを紐付けてデータを登録し直す、みたいな方法しかありませんでした（たぶん）。

しかし、今回の機能追加によって簡単にユーザーデータを取り込むことができるようになりました。
あとは、Realtime Databaseにその他のもっておきたい情報を移行[^3]してあげれば、十分にFirebaseへの移行が可能だと思います。
移行ハードルがどんどん下がってきてうれしいですね。


[^1]: すでにFirebaseおよびプロジェクトの登録とnpmのインストールが終わってある前提で書いてます。
[^3]: こちらは別途[firebase-import](https://github.com/firebase/firebase-import)を使えば良いと思います。