環境
"dependencies": {
"express": "^4.16.3",
"firebase": "^5.5.0",
"firebase-admin": "~6.0.0",
"firebase-functions": "^2.0.3"
},
"devDependencies": {
"typescript": "~2.8.3"
},
なお、今回はCloud Functions上で実行することを想定したコードになっていますが、ローカル環境で実行する際にも適用できる内容だと思われます。(未確認)
発生する問題
(問題というか、ちゃんとリファレンスなどを確認しろという話ではあるのですが、分かりづらかったので記事にします。)
firebase-adminを用いてFirestoreへ保存する処理を行ったり、アップデート処理などを行う際に値にserverTimestamp()
が含まれていると以下のようなエラーが発生します。
Error: Argument "data" is not a valid Document. Couldn't serialize object of type "ServerTimestampFieldValueImpl". Firestore doesn't support JavaScript objects with custom prototypes (i.e. objects that were created via the 'new' operator).
解決方法
上記のエラーが出たときのコードは以下の様になっていました。1
import * as admin from 'firebase-admin';
import { firestore } from 'firebase';
admin.initializeApp();
const db = admin.firestore();
firestore.settings({
timestampsInSnapshots: true
});
const docRef = await db.collection('notes').add({
createdAt: firestore.FieldValue.serverTimestamp()
});
実際に動くコードはこう
import * as admin from 'firebase-admin';
import { firestore } from 'firebase';
admin.initializeApp();
const db = admin.firestore();
firestore.settings({
timestampsInSnapshots: true
});
const docRef = await db.collection('notes').add({
- createdAt: firestore.FieldValue.serverTimestamp()
+ createdAt: admin.firestore.FieldValue.serverTimestamp()
});
serverTimestamp()
ってなにかの定数を返してあげててFirestore側でよしなにタイムスタンプに変換しているものだと思っていたのですが、どうやらそうではないことがわかりました。
わかってみればそりゃそうという程度の問題ですが、なかなか解決までにハマってしまったので、誰かのお役に立てると嬉しいです。
参考
node.js - How do I get the server timestamp in Cloud Functions for Firebase? - Stack Overflow
-
実際にはエラーハンドリングをしてあげる必要がありますがここでは省略し ↩