firestore-bigquery-export　TypeError: Cannot read properties of undefined (reading 'name')

## はじめに

[Firebase Local Emulator Suite](https://firebase.google.com/docs/emulator-suite?hl=ja)で、Firebase Extentionsの[Stream Firestore to BigQuery](https://extensions.dev/extensions/firebase/firestore-bigquery-export)を実行した際に、以下のようなエラー（`Error when mirroring data to BigQuery TypeError: Cannot read properties of undefined (reading 'name')`）が発生した。

```console
{"severity":"ERROR","message":"Error when mirroring data to BigQuery TypeError: Cannot read properties of undefined (reading 'name')\n    at Object.<anonymous> (/home/study/.cache/firebase/extensions/firebase/firestore-bigquery-export@0.1.31/functions/node_modules/@firebaseextensions/firestore-bigquery-change-tracker/lib/bigquery/index.js:104:58)\n    at walker (/home/study/.cache/firebase/extensions/firebase/firestore-bigquery-export@0.1.31/functions/node_modules/traverse/index.js:150:16)\n    at walk (/home/study/.cache/firebase/extensions/firebase/firestore-bigquery-export@0.1.31/functions/node_modules/traverse/index.js:189:3)\n    at Traverse.map (/home/study/.cache/firebase/extensions/firebase/firestore-bigquery-export@0.1.31/functions/node_modules/traverse/index.js:232:9)\n    at FirestoreBigQueryEventHistoryTracker.serializeData (/home/study/.cache/firebase/extensions/firebase/firestore-bigquery-export@0.1.31/functions/node_modules/@firebaseextensions/firestore-bigquery-change-tracker/lib/bigquery/index.js:97:42)\n    at /home/study/.cache/firebase/extensions/firebase/firestore-bigquery-export@0.1.31/functions/node_modules/@firebaseextensions/firestore-bigquery-change-tracker/lib/bigquery/index.js:67:47\n    at Array.map (<anonymous>)\n    at FirestoreBigQueryEventHistoryTracker.record (/home/study/.cache/firebase/extensions/firebase/firestore-bigquery-export@0.1.31/functions/node_modules/@firebaseextensions/firestore-bigquery-change-tracker/lib/bigquery/index.js:56:29)\n    at processTicksAndRejections (node:internal/process/task_queues:96:5)\n    at async /home/study/.cache/firebase/extensions/firebase/firestore-bigquery-export@0.1.31/functions/lib/index.js:72:9"}
```

このエラーを解決した際の備忘録を残しておく。

※エラーの原因・解決方法について認識の誤りなどあれば、ご指摘頂けると幸いです。

## 原因（の仮説）

エラーが発生したコードを確認した所、以下のようにモジュールをインポートしており、これが原因だと思われる。

```js:/home/study/.cache/firebase/extensions/firebase/firestore-bigquery-export@0.1.31/functions/node_modules/@firebaseextensions/firestore-bigquery-change-tracker/lib/bigquery/index.js
const firebase = require("firebase-admin");
...
    serializeData(eventData) {
        ...
                if (property.constructor.name ===
                    firebase.firestore.DocumentReference.name) {
                    this.update(property.path);
                }
        ...
    }
```

具体的には、firebase.firestoreはfunctionとしてexportされており、`firebase.firestore()`は実行可能だが、`firebase.firestore`にはプロパティがない。そのため、`firebase.firestore.DocumentReference`がundefinedになっており、`Cannot read properties of undefined (reading 'name')`というエラーになっていると思われる。

元のTypeScriptのコードだと、[functionのfirestore](https://github.com/firebase/firebase-admin-node/blob/master/src/firestore/firestore-namespace.ts#L20)と[namespaceのfirestore](https://github.com/firebase/firebase-admin-node/blob/master/src/firestore/firestore-namespace.ts#L23)の2つが定義されてるようだが、これをJavaScriptにビルドした際に、functionのみがexportされているのだと思われる。

## 解決方法

モジュールのインポートを以下のように変更し、firestoreのエントリーポイントを利用する。具体的には、以下のようなコードに書き換える。

```js
const firestore = require("firebase-admin/firestore"); // <- firestoreのエントリーポイントを利用
...
    serializeData(eventData) {
        ...
                if (property.constructor.name ===
                    firestore.DocumentReference.name) {
                    this.update(property.path);
                }
        ...
    }
```

これについては、[名前空間の代わりにモジュールを使用する](https://firebase.google.com/docs/admin/migrate-node-v10?hl=ja#node.js)で推奨されている実装であり、修正方法として大きくずれている事はないと思われる。

> v10 より、Admin Node.js SDK は名前付きエクスポートを使用する複数のモジュール エントリ ポイントを提供します。今後はグローバルな admin 名前空間ではなく、これらの新しいエントリ ポイントを使用して SDK のさまざまな API にアクセスすることをおすすめします。