Firebase Admin SDKで1日のAuthenticationユーザ数を集計してみた(最大5倍)

最近リリースした積読用のWebサービスの『[積読ハウマッチ](https://tsundoku.site)』、
[Qiita記事](https://qiita.com/kira_puka/items/8c1d1240c3aa200cbec0)を書いた結果、たくさんの方々が登録者してくれました:tada::tada:



ちゃんと計測してみたいなと思ってたら、[Firebase Admin SDK](https://firebase.google.com/docs/auth/admin/manage-users?hl=ja#list_all_users)を使うと、
Firebase Authの登録日から日毎のユーザ数を集計できそうなので、試してみました!

#### できたグラフはこちら

こんなグラフを出したかったのです...

![1日の登録者数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/8a89923e-cf99-626b-561e-6bf25c3dafa3.png)

ちなみに、[前の記事](https://qiita.com/kira_puka/items/8c1d1240c3aa200cbec0)を書いたのが8/14で、1日トレンドが8/16なので、約5倍...うれしい...:sob:
ただ、[INTERNET Watch](https://internet.watch.impress.co.jp/docs/yajiuma/1201709.html)さんや[nabettu](https://blog.nabettu.com/entry/bugbash)さんにも紹介いただいていたので、純粋な数字ではない...

#### このグラフを出すためには、こんなCSVがほしい...

`日付`と`その日の登録ユーザ数`の２カラムのデータがあれば、

```text
2019-08-11	3
2019-08-12	12
2019-08-13	46
2019-08-14	13
2019-08-15	38
2019-08-16	65
2019-08-17	18
```

Googleスプレッドシートでグラフを出せるので、

<img width="932" alt="スクリーンショット 2019-08-18 17.46.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/a4bb8f05-82f9-d46c-2265-92bf8258ad39.png">

とりあえず、これが出したいなと。。(*´ω｀*)

#### ユーザ数を日毎に集計するソース

Firebase Authのユーザの一覧を取得して、集計して、
`console.log()`で出力するソースです!!

ローカルPCでfirebase-adminを使うときの初期設定とかはこちらを参照
- [ローカルPCからfirebase-adminを使ってFirestoreを操作する(管理ツール) - くらげになりたい。](https://www.memory-lovers.blog/entry/2019/07/25/073000)

```javascript
const dayjs = require("dayjs");
const admin = require("firebase-admin");

// 配置したサービスアカウントの秘密鍵を取得
const serviceAccount = require("./key/XXXXX.json");

// firebase-adminを初期化
admin.initializeApp({ credential: admin.credential.cert(serviceAccount) });

// firestoreのインスタンスを取得
const db = admin.firestore();

/**
 * Firebase Authからユーザの一覧を取得する関数。
 * 最大1000件の取得条件があるので、再起で呼び出す
 */
async function listAllUsers(users = [], nextPageToken) {
  try {
    const res = await auth.listUsers(1000, nextPageToken);
    res.users.forEach(userRecord => users.push(userRecord.toJSON()));

    if (res.pageToken) await listAllUsers(users, res.pageToken);
  } catch (error) {
    console.log("Error listing users:", error);
  }
  return users;
}

// ****************************
// * MAIN
// ****************************
async function main() {
  console.log(`***** START MAIN`);

  // Firebase Authのユーザ数を取得
  const users = await listAllUsers();

  // 日付ごとに集計
  const summary = {};
  users.forEach(userRecord => {
    const creationTime = userRecord.metadata.creationTime;
    const createAt = dayjs(creationTime).format("YYYY-MM-DD");
    if (createAt in summary) summary[createAt] = summary[createAt] + 1;
    else summary[createAt] = 1;
  });

  // 集計結果を出力
  Object.entries(summary)
    .sort((a, b) => dayjs(a[0]).diff(dayjs(b[0]))) // 日付の昇順にソート
    .forEach(([key, val]) => console.log(`${key},${val}`)); // 書き出し
  console.log(`***** END   MAIN`);
  process.exit(0); // プロセスが終了しない時があるので、exitしてます...
}

main().then();
```

中身的にはシンプルで、
1. Firebase Authでユーザの一覧を取得してきて
2. 日付ごとに集計
3. 集計した結果をCSV形式で出力

なお、日付の計算は[dayjs](https://github.com/iamkun/dayjs)を使っています。
必要に応じて`npm install dayjs --save`などでインストールしてください!


#### Firebase Authではこんな情報を取得できます

> res.users.forEach(userRecord => users.push(userRecord.toJSON()));

の部分の`userRecord.toJSON()`では、こんな情報が取得できます。

```json
{
  "uid": "....",
  "email": undefined,
  "emailVerified": false,
  "displayName": "めもらば@公式",
  "photoURL": "https://xxxxxx.png",
  "phoneNumber": undefined,
  "disabled": false,
  "metadata": {
    "lastSignInTime": "Tue, 06 Aug 2019 08:46:10 GMT",
    "creationTime": "Mon, 22 Jul 2019 16:24:06 GMT"
  },
  "passwordHash": undefined,
  "passwordSalt": undefined,
  "customClaims": undefined,
  "tokensValidAfterTime": "Mon, 22 Jul 2019 16:24:06 GMT",
  "providerData": [
    {
      "uid": "xxxxxx",
      "displayName": "めもらば@公式",
      "email": "xxxx@email.com",
      "photoURL": "https://xxxx.png",
      "providerId": "twitter.com",
      "phoneNumber": undefined
    }
  ]
}
```

いろいろできるので、ユーザ管理用にスクリプトとかを用意しておくのもよさそう(*´ω｀*)

#### おわりに

以下の記事でも書いたけど、firebase-admin便利...ヽ(=´▽`=)ﾉ
- [ローカルPCでfirebase-adminを使って一括削除/一括更新する - Qiita](https://qiita.com/kira_puka/items/e4d4846f394d36e29776)

ちなみに、計測した対象のサービスはこちらです♪
積読総額ランキングや人気の本などもあるので、よかったらあそんでもらえれば!!

積んでる本の総額がわかる読書管理サービス
『[積読ハウマッチ](https://tsundoku.site)』

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

# 参考にしたサイト
- [ユーザー管理  |  Firebase](https://firebase.google.com/docs/auth/admin/manage-users?hl=ja#create_a_user)
- [UserMetadata | Admin Node.js SDK  |  Firebase](https://firebase.google.com/docs/reference/admin/node/admin.auth.UserMetadata)
- [iamkun/dayjs: ⏰ Day.js 2KB immutable date library alternative to Moment.js with the same modern API](https://github.com/iamkun/dayjs)
- [JavaScript つい忘れてしまう配列のソート方法 - Qiita](https://qiita.com/PianoScoreJP/items/f0ff7345229871039672)