我在编写从firestore读取数据的计划函数时遇到了麻烦。该函数每1分钟成功运行一次,但现在的问题是从firestore读取数据。我使用async-await,因为我想在读取之后循环数据,然后做一些更新。请帮助我是第一次使用firebase功能。下面是我的函数。我一直得到这个错误无法读取未定义的属性映射
exports.checkDefaultedPledges = functions.pubsub.schedule("every 1 minutes").onRun( async
(context) => {
console.log("This will be run every 2 minutes!");
const time = new Date().getTime();
const snapshot = db.collection("pledges").get();
const res = await snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
console.log(res);
return null;
});
我是否可以在不使用.then()的情况下编写此函数?
我遇到的问题是在读取时没有返回数据数据。
调用get()
时需要使用await
,因为它是一个异步方法。
另一方面,你不应该在const res = await snapshot.docs.map()
中使用await
,因为docs
是一个简单的属性(这里没有异步性)。
如果您想更新pledges
集合中的所有文档,您可以使用批处理写入,如下所示:
exports.checkDefaultedPledges = functions.pubsub.schedule("every 1 minutes").onRun(async (context) => {
const time = new Date().getTime();
const snapshot = await db.collection("pledges").get();
const batch = db.batch();
snapshot.forEach(doc => {
batch.update(doc.ref, { "updateTime": time });
})
return batch.commit();
});
请注意,批处理写入可以包含多达500个操作:所以如果你知道你的集合有/将有超过500个文档,你应该使用Promise.all()
如下:
exports.checkDefaultedPledges = functions.pubsub.schedule("every 1 minutes").onRun(async (context) => {
const time = new Date().getTime();
const snapshot = await db.collection("pledges").get();
const promisesArray = snapshot.docs.map(doc => doc.ref.update({ "updateTime": time }));
return Promise.all(promisesArray);
});
注:
使用FieldValue.serverTimestamp()
而不是使用JSDate()
是最佳实践,特别是当您从客户端应用程序编写Firestore时。serverTimestamp
"返回与set()
或update()
一起使用的哨兵,以包含服务器生成的时间戳在书面数据"
由于云函数是由服务器执行的,所以它不是必须的,但您可以按照以下方式调整您的代码:
const time = admin.firestore.FieldValue.serverTimestamp();