Serverless Framework で Firebase SDK を使用時、 "util.Long.fromValue is not a function" と出た時の対応
June 22, 2021
同事象で苦しむ人は稀と思われるので、この記録が役に立つかは不明。
発端 #
- Serverless Framework にて AWS Lambda 上で動くコードを開発中。
- serverless-offline にて、ローカルで起動している Firebase Local Emulator の Cloud Firestore に以下のコードを実行するとエラーが発生。
(試してはいませんが、ローカル環境で上記が発生している場合、デプロイ後の本番の Lambda 上でも同様にエラーとなるはずです。)
import admin from 'firebase-admin';
import serviceAccount from '***-firebase-adminsdk.json';
admin.initializeApp({ credential: admin.credential.cert(serviceAccount as admin.ServiceAccount) });
const docData = {
stringExample: 'Hello world!',
booleanExample: true,
numberExample: 3.14159265,
dateExample: admin.firestore.FieldValue.serverTimestamp(),
arrayExample: [5, true, 'hello'],
nullExample: null,
objectExample: {
a: 5,
b: {
nested: 'foo',
},
},
};
db.collection('data').doc('one').set(docData);
エラーメッセージは以下
Request message serialization failure: util.Long.fromValue is not a function
送っているパラメータを一つずつ確認していくと、どうやら以下の3つを送ろうとすると上記エラーになる。タイムスタンプと配列とマップがダメな様子。
- dateExample
- arrayExample
- objectExample
原因 #
いろいろ調べてみると下記が原因だった。(参考にしたソースは本記事の最後にまとめます。)
- node モジュールの
firebase-admin
の依存先を辿っていくと、依存パッケージの一つにlong
がある。バージョンは 4.0.0 以上が指定されている。 serverless
の依存先を辿っていくと、これも依存パッケージの一つにlong
がある。バージョンは 1.1.2 が指定されている。- 古いバージョンの
long(< 2.1.0)
にはfromValue method
が存在しない。 package.lock.json
で最終的に指定されているlong
を見ると以下になっていた。
"long": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/long/-/long-1.1.2.tgz",
"integrity": "sha1-6u9ZUcp1UdlpJrgtokLbnWso+1M=",
"dev": true
},
ご覧の通り 1.1.2 の方が適用されている。
理由 #
- 古いバージョンと新しいバージョンの
long
どちらが最終的に適用されるかは、package-lock.json
内で読み込む順番によって決まり、先に読み込んだ方が適用される。 - 私の場合、
package-lock.json
ではserverless
の方がfirebase-admin
よりも先に記載されており、そのため 1.1.2 のlong
が最終的に適用されていた。
解決策 #
- 新しいバージョンの
long
を適用させる必要がある。 - そのためには、
firebase-admin
をserverless
よりも先に記載すれば良い。 package-lock.json
へ記載される順番は、npm install
した順番によって決まるため、まずはnpm i firebase-admin
その後npm i serverless
すれば良い。
なお、 package.json
では dependencies
に firebase-admin
を、 devDependencies
に serverless
を 指定しているのが通常と思われるが、その状態であれば、一度 package-lock.json
を削除した後 npm install
すれば firebase-admin
の方が上位に記載されているはず。
原因振り返り #
私の場合は、まず npm install --save-dev serverless
し、その後 npm install firebase-admin
していたため、本事象が発生する状態となっていた。
解決後の状態 #
package-lock.json
を確認すると、 long
のバージョンが 4.0.0 になっていることが確認できた。firebase-admin
を利用したコードも問題なく動いた。
"long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},