【问题标题】:How do I schedule a cloud function to update every user in the Firebase Realtime database?如何安排云功能来更新 Firebase 实时数据库中的每个用户?
【发布时间】:2021-07-06 16:22:29
【问题描述】:

我已将云调度程序连接到我的项目并准备好每天运行。我有数据附加到我想每天更新的用户。

likesforday
    uid1
       -Amount : 43
    uid2
       -Amount : 567

我需要将所有数量设置为 0。

我可以正确更新一条记录,但我不知道如何更新实时数据库中的每个用户。我还希望它是一个原子更新,所以要么是所有用户,要么没有。

有很多关于使用 onWrite onCreate 等的指南...但我需要 scheduler.onRun 每天更新所有数量。

我尝试过类似的方法

exports.resetdailytaps = functions.pubsub
  .schedule("every day 00:00")
  .onRun(async () => {
  console.log("starting");

let updates = {};
let qu = database.ref(`/likesforday/{uid}`).orderByChild("amount");
const snap = await qu.once("value");
snap.forEach((child) => {
  updates[child.key] = 0;
  console.log("childkey: " + child);
});

return database.ref().update(updates);

和其他变体,但无法使其工作。

谢谢!

【问题讨论】:

    标签: firebase firebase-realtime-database google-cloud-firestore google-cloud-functions google-cloud-scheduler


    【解决方案1】:

    您问题的重点是:

    我也希望它是一个原子更新,所以要么全部 用户或没有用户。

    为此,您需要使用update() 方法,就像您在问题中所做的那样:使用此方法进行的同时更新是原子的。要么全部更新成功,要么全部更新失败。

    以下方法可以解决问题:

      exports.resetdailytaps = functions.pubsub
        .schedule('every day 00:00')
        .onRun(async () => {
          console.log('starting');
          const db = firebase.database();
          const updates = {};
    
          const snapshot = await db.ref('likesforday').once('value');
    
          snapshot.forEach((childSnapshot) => {
            updates['/likesforday/' + childSnapshot.key + '/Amount'] = 0;
          });
          
          return db.ref().update(updates);
        });
    

    【讨论】:

    • 是的!谢谢你工作得很好。只需从 firebase.database() 更改为 admin.database,然后将 firebase.database().ref().update( 更改为 admin.database.ref.update( 非常感谢!@Renaud Tarnec
    • 很高兴能帮到你!是的,您是对的:由于此代码位于 Cloud Function 中,因此我们需要使用 Admin SDK。为了清晰和未来的读者,我会调整答案。
    【解决方案2】:

    我认为没有必要orderByChild,您只是将所有子节点的数量设置为0。请尝试运行以下代码:

    const updates = []
    
    database.ref("likesforday").once("value").then((snapshot) => {
      Object.keys(snapshot).forEach((user) => {
        updates.push(database.ref(`likesforday/${user}`).update({Amount: 0}))
      })
    })
    
    await Promise.all(updates)
    

    对于 cron,您也可以尝试 0 0 * * * 在每个午夜运行。

    【讨论】:

    • 感谢您的回复!我在您的建议中添加了一些日志语句。 .then((snapshot) => { console.log("snapshot: " + snapshot); Object.keys(snapshot).forEach((user) => { console.log("user: " + user); updates.push(user.ref.update({ Amount: 0 })); }); }) 看起来快照是一个 [object Object] 而用户是 _database。我收到异常:“无法读取未定义的属性更新”。看起来 user.ref 是未定义的。 @Dharmaraj
    • 此解决方案将产生错误,因为user 没有ref 属性。此外,Promise.all() 不确保所有用户都更新或没有更新Promise.all() 在任何输入承诺拒绝或非承诺抛出错误时立即拒绝:被拒绝之前的所有输入承诺都将被成功执行。
    • 嘿@cdub,你能试试更新的解决方案吗?
    • @RenaudTarnec 解决方案对我有用。 :stackoverflow.com/a/68266531/5900508
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-20
    • 2023-04-08
    • 2023-03-09
    • 2020-05-15
    • 2020-05-18
    相关资源
    最近更新 更多