【问题标题】:Firebase Scheduled Function to read Data from Firestore and then do some updaatesFirebase 计划函数从 Firestore 读取数据,然后进行一些更新
【发布时间】:2021-08-18 08:28:46
【问题描述】:

我在编写计划函数以从 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() 的情况下编写此函数?

【问题讨论】:

  • "我是否可以在不使用 .then() 的情况下编写此函数?" => 是的。您到底想更新什么(哪些文档和哪些数据?快照中的所有文档?等等)?
  • @RenaudTarnec 在更新之前。我遇到的问题是读取数据时没有返回数据。我收到此错误无法读取未定义的属性映射。
  • 你需要做const snapshot = await db.collection("pledges").get();,因为get()是异步的。而且你不应该在 const res = await snapshot.docs.map() 中使用 await,因为 maps 是一个简单的属性(这里没有异步性)。
  • 以上评论中的错字。应该阅读:“因为docs 是一个简单的属性(这里没有异步性)”
  • 谢谢@RenaudTarnec。有效。我现在明白发生了什么

标签: javascript node.js firebase google-cloud-firestore google-cloud-functions


【解决方案1】:

我遇到的问题是读取时没有返回数据 数据。

调用get()时需要使用await,因为它是异步方法。

另一方面,你不应该在const res = await snapshot.docs.map() 中使用await,因为docs 是一个简单的属性(这里没有异步性)。


如果您想更新pledges 集合中的所有文档,可以使用batched write,如下所示:

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() 而不是使用JS Date() 是最佳实践,尤其是当您从客户端应用程序写入Firestore 时。 serverTimestamp "返回与set()update() 一起使用的标记,以在写入的数据中包含服务器生成的时间戳

由于云函数是由服务器执行的,它不是必须的,但您可以按如下方式调整您的代码:

const time = admin.firestore.FieldValue.serverTimestamp();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-05
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    相关资源
    最近更新 更多