Javascript 在实时数据库:Firebase Cloud函数中将值的所有实例设置为null

Javascript 在实时数据库:Firebase Cloud函数中将值的所有实例设置为null,javascript,typescript,firebase-realtime-database,google-cloud-functions,Javascript,Typescript,Firebase Realtime Database,Google Cloud Functions,我想通过将userID设置为null来擦除连接到数据库中许多不同post键的特定userID的所有值。userid附加到路径中的post键:posts/ivies/userid in my database。以下是数据库的外观: 因此,我决定运行以下for循环来筛选userID并将其设置为null: exports.wipeData = functions.https.onRequest(async (req, res) => { const original = 'ppPXA8Mva

我想通过将userID设置为null来擦除连接到数据库中许多不同post键的特定userID的所有值。userid附加到路径中的post键:posts/ivies/userid in my database。以下是数据库的外观:

因此,我决定运行以下for循环来筛选userID并将其设置为null:

exports.wipeData = functions.https.onRequest(async (req, res) => {
 const original = 'ppPXA8MvaSRVbmksof0ByOzTxJ92';
    const snapshot = await admin.database().ref('/posts/ivies/userIDs/');
    console.log((snapshot));

    for (let value in snapshot.val) {
      if (value == original) {
      snapshot.val.set("null")
      }
      else {
        console.log(value)
      }
    }

    res.redirect(303, snapshot.ref.toString());

// [END adminSdkPush]
});

尽管此函数可以部署和运行,但它不会像预期的那样将“ppPXA8MvaSRVbmksof0ByOzTxJ92”变为“null”。感谢您的帮助。

我不熟悉firebase云函数,但在常规客户端中,firebase代码
val
需要作为函数调用,您必须等待引用中的值。你可以试试:

exports.wipeData = functions.https.onRequest(async (req, res) => {
  const original = 'ppPXA8MvaSRVbmksof0ByOzTxJ92';
  const userIDs = await admin.database().ref('/posts/ivies/userIDs/');
  userIDs.once("value", snapshot => {
    var lookup = snapshot.val();
    for (let key in lookup) {
      var value = lookup[key];
      if (key == value) {
        userIDs.child(key).set(null);
      }
    }
    res.redirect(303, userIDs.ref.toString());
  });
});

您的一般方法似乎很好,但是您有一些bug

这应该更好地发挥作用:

exports.wipeData = functions.https.onRequest(async (req, res) => {
  const original = 'ppPXA8MvaSRVbmksof0ByOzTxJ92';
  const ref = admin.database().ref('/posts/ivies/userIDs/');
  const query = ref.orderByValue().equalTo(original);

  const results = await query.once('value');
  const updates = {};
  results.forEach((snapshot) => {
    updates[snapshot.key] = null;
  });

  await ref.update(updates);

  res.status(200).send(JSON.stringify(updates));
})
主要变化:

  • 您的
    snapshot
    变量尚未包含任何数据,因为您没有从数据库中读取数据。我的代码中的
    一次('value')
    执行该读取
  • 此代码使用查询仅选择具有正确值的节点。当用户数量增加时,这将显著降低数据库负载(和成本)
  • 这段代码首先将所有更新收集到一个对象中,然后将它们作为一个调用发送到数据库
  • await ref.update(updates)
    中的
    await
    可能是主要修复程序,因为它确保只有在数据库写入完成后才执行重定向

您的代码以状态代码303结束,并且没有更新按键哦,哎呀,我的代码错了,我没有足够清楚地阅读问题。我更改了它,以便现在与值而不是键进行比较。如果它能工作,我仍然会感到惊讶,但希望它能让你更接近你所需要的。你的重定向仍然会在写操作完成之前发生,这意味着它们会被中止。Lou需要对所有set操作执行
Promise.all()
,以确保在重定向发生之前完成写入。Hmm。当我尝试使用URL“”运行函数时,您的函数正在抛出403“您的客户端没有从此服务器获取URL/%7B%7D的权限”。wipeData仍然根据服务器日志运行,但ID保留在数据库中注意,我是数据库的所有者,函数以状态代码303Ah结束,我现在意识到我的代码在重定向正文中发送常规响应。我可能会使用
res.send()
进行测试,然后使用您想要的任何生产重定向。我对您的代码所做的更改中更重要的部分希望可以从我的逐条解释中清楚地看到。