您的代码存在三个主要问题:
- 通过使用
DocumentReference#update(newData) 将更改与 Cloud Firestore 同步,如果您的 Cloud Firestore 中不存在 /lamps/{id} 文档,您的代码将引发错误。
- 由于您使用的是
onWrite() RTDB触发器,您需要处理云函数指向的数据已被删除的情况。目前,如果您的函数不存在(如val == null),则会出错。
- 如果传入数据中省略了
Humidity 或 Temperature(区分大小写!),尝试将其数据添加到 Cloud Firestore(将为 undefined)将引发有关无效数据类型的错误。
对此最简单的解决方法是酌情使用DocumentReference#set(newData, { merge: true }) 和DocumentReference#delete(),同时使用suitable security rules 保护您的RTDB,以确保您的传入数据形状良好。
import * as admin from "firebase-admin";
import * as functions from "firebase-functions";
admin.initializeApp();
exports.addtoFirestore = functions.database.ref('lamps/{id}').onWrite(async (snapshot, context) => {
const id = snapshot.key;
const docRef = admin.firestore().collection('lamps').doc(id);
if (!snapshot.exists) {
// data deleted, delete linked Firestore data
return docRef.delete()
.catch((error) => {
console.error(`Failed to sync data deletion for /lamps/${id}: `, error);
// optionally rethrow it:
// throw error;
});
}
const { Humidity, Temperature } = snapshot.val();
return docRef.set({ Humidity, Temperature }, { merge: true })
.catch((error) => {
console.error(`Failed to sync data to Firestore for /lamps/${id}: `, error);
// optionally rethrow it:
// throw error;
});
});
确保实施相关的安全规则:
{
"rules": {
"lamps": {
"$lampId": {
// must be logged in to read/write
// because we restrict this heavily below, you
// could make this "true", but I don't recommend it
".write": "auth != null",
".read": "auth != null",
"Humidity": {
// if present, must be number
".validate": "newData.isNumber()"
},
"Temperature": {
// if present, must be number
".validate": "newData.isNumber()"
},
"$other": {
// block all other data
".validate": "false"
}
}
}
}
}
其他说明: