はじめに
Firebase Local Emulator Suiteで、Firebase ExtentionsのStream Firestore to BigQueryを実行した際に、以下のようなエラー(Error when mirroring data to BigQuery TypeError: Cannot read properties of undefined (reading 'name')
)が発生した。
{"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"}
このエラーを解決した際の備忘録を残しておく。
※エラーの原因・解決方法について認識の誤りなどあれば、ご指摘頂けると幸いです。
原因(の仮説)
エラーが発生したコードを確認した所、以下のようにモジュールをインポートしており、これが原因だと思われる。
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とnamespaceのfirestoreの2つが定義されてるようだが、これをJavaScriptにビルドした際に、functionのみがexportされているのだと思われる。
解決方法
モジュールのインポートを以下のように変更し、firestoreのエントリーポイントを利用する。具体的には、以下のようなコードに書き換える。
const firestore = require("firebase-admin/firestore"); // <- firestoreのエントリーポイントを利用
...
serializeData(eventData) {
...
if (property.constructor.name ===
firestore.DocumentReference.name) {
this.update(property.path);
}
...
}
これについては、名前空間の代わりにモジュールを使用するで推奨されている実装であり、修正方法として大きくずれている事はないと思われる。
v10 より、Admin Node.js SDK は名前付きエクスポートを使用する複数のモジュール エントリ ポイントを提供します。今後はグローバルな admin 名前空間ではなく、これらの新しいエントリ ポイントを使用して SDK のさまざまな API にアクセスすることをおすすめします。