Firebase Authentication にデータをインポート・エクスポートおよびデリートする方法

# はじめに
`Firebase Authentication` にデータをインポート・エクスポートおよびデリートする方法をまとめます。
`Firebase Authentication` にデータを出し入れするときがあるかと思います。
私の場合は、既存のインフラから新しいインフラに移行する際にデータを出し入れする必要がありました。

# 対象読者
・インフラ初級者
・Firebase Authentication に慣れていない方
・`Firebase Authentication` にデータを出し入れする方法をサクッと知りたい方

# 参考

https://firebase.google.com/docs/cli/auth?hl=ja

https://qiita.com/0xoshio/items/ec4d8bfb051b6c91b059

# `Firebase Authentication` でのデータ移行の流れ
1. sample_projectA からデータをエクスポートする
2. sample_projectB のテストデータを削除する（データが空であればスキップ）
3. 1 でエクスポートしたsample_projectA のデータを、sample_projectB にインポートする


# 1. sample_projectA からデータをエクスポートする
```bash
$ firebase auth:export file_name.json --project=sample_projectA

Exporting accounts to file_name.json
✔  Exported 500 account(s) successfully.
```

::: note warn
サービスアカウントの権限を確認してください。
権限が不足していると、パスワードを適切にエクスポートできない場合がありました。
:::

# 2. sample_projectB のテストデータを削除する（データが空であればスキップ）
ここではスクリプトを作成して、`Firebase Authentication` のデータを削除します。

```javascript:firebase_authentication_user_delete_all.js
const admin = require("firebase-admin");
const _ = require('lodash/array');
// 対象のFirebaseプロジェクトに対応するサービスアカウントファイルを同じディレクトリに配置
const serviceAccount = require("./serviceAccountKey.json");
const databaseURL = "https://sample_projectA.firebaseio.com"

admin.initializeApp({
  credential: admin.credential.cert(serviceAccount),
  databaseURL: databaseURL
});

const deleteAllUsers = (nextPageToken) => {
  admin
    .auth()
    .listUsers(1000, nextPageToken)
		.then((listUsersResult) => {
      const uids = listUsersResult.users.map(userRecord => {
        return userRecord.uid;
      });

			admin
				.auth()
				.deleteUsers(uids)
				.then((deleteUsersResult) => {
					console.log(`Successfully deleted ${deleteUsersResult.successCount} users`);
					console.log(`Failed to delete ${deleteUsersResult.failureCount} users`);
					deleteUsersResult.errors.forEach((err) => {
						console.log(err.error.toJSON());
					});
				})
				.catch((error) => {
					console.log('Error deleting users:', error);
				});
      if (listUsersResult.pageToken) {
        deleteAllUsers(listUsersResult.pageToken);
      }
    })
    .catch((error) => {
      console.log('Error listing users:', error);
    });
};

deleteAllUsers();
```

```bash
$ node firebase_authentication_user_delete_all.js

Successfully deleted 50 users
Failed to delete 0 users
```

# 3.  1 でエクスポートしたsample_projectA のデータを、sample_projectB にインポートする
![スクリーンショット 2023-02-24 11.36.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916052/5238b996-33e2-5a8f-34d9-33a02f12331c.png)

↑の3点リーダーを押下して、パタメーターを確認します。

![スクリーンショット 2023-02-24 11.37.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/916052/a69be955-2cf5-315b-b1b7-2f6da813c701.png)

::: note warn
パスワードハッシュパラメーターは、エクスポート元のプロジェクトを参照してください。
今回の場合は、sample_projectA です。
:::

```bash
firebase auth:import file_name.json \
    --hash-algo=your_algo \
    --hash-key=your_key \
    --salt-separator=your_salt \
    --rounds=number \
    --mem-cost=number \
    --project=sample_projectB

Processing file_name.json (10000 bytes)
Starting importing 500 account(s).
✔  Imported successfully.
```

これで`Firebase Authentication` のデータを入れ替えることができました。

# 終わりに
コマンドに渡すオプションを適切に設定していれば簡単にデータを入れ替えることができました。
データを一旦削除するためのコマンドは用意されていないので、スクリプトを実行する必要があります。