データがTimestampオブジェクトのはずが、そうなっていない
データベースに格納されているTimestampオブジェクトを扱うと、データ形式がTimestampでないようでエラーが出ていました。
const latestRecord = latestRecordSnapshot.docs[0].data();
console.log("latestRecord:", latestRecord);
if (latestRecord.timestamp &&
typeof latestRecord.timestamp.toDate === "function") {
// FirestoreのTimestampをJavaScriptのDateに変換
const latestTimestamp = latestRecord.timestamp.toDate();
またデータベースの格納を修正したらそこでもエラーが出るようになってしまいました。
・コード
// FirestoreのTimestampオブジェクトを使用して現在時刻を取得
const timestamp = admin.firestore.Timestamp.now();
// 温度とMACアドレスをFirestoreデータベースに保存
const writeResult = await admin.firestore()
.collection("temperatureData")
.add({
temperature: temperature,
macAddress: macAddress,
timestamp: timestamp,
alertFlag: alertFlag,
});
・コマンドで上記を実施した結果
$ curl -X POST http://127.0.0.1:5001/temperature-measurement-b3fcd/us-central1/XXX \
-H "Content-Type: application/json" \
-d '{"temperature": "27.5", "macAddress": "YYY"}'
{"error":"Cannot read properties of undefined (reading 'now')"}%
上についてはtimestampが定義されていないため起きたエラーになります。修正したものは以下になります。
// FirestoreのTimestampを直接インポート
const {Timestamp} = require("firebase-admin/firestore");
// Firebaseアプリがまだ初期化されていない場合のみ初期化を実行
if (admin.apps.length === 0) {
admin.initializeApp();
}
// FirestoreのTimestampオブジェクトを使用して現在時刻を取得
const timestamp = Timestamp.now();
Timestampを宣言することによりエラーになることを回避できました。
タイムゾーンの指定をしておらず、作成したオブジェクトの日付が意図しない値になる
以下のようなコードを作り、当日の開始時刻、終了時刻、翌日の開始時刻と同じ時間のオブジェクトを作成しました。
// タイムゾーンを指定して日時を生成
const now = new Date();
const currentDateTime = new Date(now.
toLocaleString("en-US", {timeZone: "Asia/Tokyo"}));
// 開始時刻と終了時刻を指定したタイムゾーンで生成
const startTime = new Date(now.getFullYear(),
now.getMonth(), now.getDate(), startHour, startMinute);
const endTime = new Date(now.getFullYear(),
now.getMonth(), now.getDate(), endHour, endMinute);
// 翌日の日付に設定
const tomorrow = new Date(now);
tomorrow.setDate(now.getDate() + 1);
// 開始時刻と終了時刻を指定したタイムゾーンで生成
const startTimeTomorrow = new Date(tomorrow.getFullYear(),
tomorrow.getMonth(), tomorrow.getDate(), startHour, startMinute);
しかし、結果は以下のような意図しない動作になりました。
currentDateTime:正確
startTime:意図はプログラム動作中の同日だが、1日前になっている。
endTime:意図はプログラム動作中の同日だが、1日前になっている。
startTimeTomorrow:意図はプログラム動作中の翌日だが、動作中の日付になっている。
原因は、それぞれのオブジェクト作成時にタイムゾーンの指定がなされておらず、UTCで参照してしまい、意図するGMT+0000(日本時間)でなくなり、日付が違っていたためでした。
以下のように修正することで解決しました。
// 開始時刻と終了時刻を指定したタイムゾーンで生成
const startTime = new Date(now.toLocaleString("en-US",
{timeZone: "Asia/Tokyo"})).setHours(startHour, startMinute);
const endTime = new Date(now.toLocaleString("en-US",
{timeZone: "Asia/Tokyo"})).setHours(endHour, endMinute);
// 翌日の日付に設定
const tomorrow = new Date(now);
tomorrow.setDate(now.getDate() + 1);
// 開始時刻と終了時刻を指定したタイムゾーンで生成
const startTimeTomorrow = new Date(tomorrow.toLocaleString("en-US",
{timeZone: "Asia/Tokyo"})).setHours(startHour, startMinute);