【问题标题】:Is it possible to update the data of a child when the Key is generated automatically by the Firebase?Firebase自动生成密钥时,是否可以更新孩子的数据?
【发布时间】:2019-09-17 19:22:45
【问题描述】:

我正在尝试在 Firebase 自动生成密钥时更新特定数据。

我尝试了下面的代码。它仍然不起作用:(

我试过了:

  function updateHomeworkStatus(agent) {

    var chosenHw = request.body.queryResult.outputContexts[0].parameters.chosenHw;
    var status = request.body.queryResult.outputContexts[0].parameters.status;

    var query = admin.database().ref('Homework').orderByChild('Name').equalTo(chosenHw);
    query.once('value')
      .then(snapshot => {
        // Once we have a result, we can use the reference to it
        var snapshotRef = snapshot.ref;

        // We want to change the value of Completed field, 
        // so we get a reference to that
        var completedRef = snapshotRef.child('CompletionStatus');

        // We can then set it, since we have a direct reference to the
        // field and there is nothing else that will be changed.
        completedRef.update(status);
      });

    agent.add("Status has been changed to " + status);


  }

例如(我附上了我的火力基地的图片):

Dialogflow:您要更改的作业的名称是什么 完成状态? (我已经这样做了)

当用户说“编码工作表 7”并且所需状态为“是”时, 具体数据会发生变化。 (这个编码部分我需要 hep)。

所以预期的结果将是“编码工作表 7”的 CompletionStatus 将更改为“否”。

【问题讨论】:

    标签: javascript node.js firebase firebase-realtime-database dialogflow-es


    【解决方案1】:

    您当前解决方案的关键问题是 Firebase RT 数据库调用是异步的,您无需等待这些调用返回结果即可响应您的用户。

    此外,Firebase RT Database Queries 将返回结果列表/集合。因此,要查看查询结果,您必须使用snapshot.forEach() 来遍历返回的数据。

    如果要使用更新操作update(),则传递给函数的参数必须是包含'path/to/value': value 对的对象。请参阅此Firebase Blog post 了解更多信息。因此,对于您的代码,您可以使用 `update({ CompletionStatus: status }) 更新“CompletionStatus”,而完全不必担心使用 child()。

    您还需要考虑错误情况,例如文件不存在、名称重复和 Firebase RTDB 错误。我在下面为这些添加了错误处理脚手架。

    // somewhere near the top of your request handler
    const RESULT_NOT_FOUND = -1;
    const RESULT_DUPLICATED = -2;
    
    function updateHomeworkStatus(agent) {
      var outputContext = request.body.queryResult.outputContexts[0];
      var chosenHw = outputContext.parameters.chosenHw;
      var status = outputContext.parameters.status;
    
      var query = admin.database().ref('Homework').orderByChild('Name').equalTo(chosenHw);
    
      // Remember to return the promise
      return query.once('value')
        .then(snapshot => {
          // "snapshot" is the query result, it's children contain the queried data
    
          if (!snapshot.hasChildren()) {
              throw RESULT_NOT_FOUND;
          } else if (snapshot.numChildren() != 1) {
              throw RESULT_DUPLICATED;
          }
    
          // init variable to store DatabaseReference
          var firstResultRef;
    
          // only one child at this point, so only called once
          snapshot.forEach(childSnapshot => {
            firstResultRef = childSnapshot.ref;
            return true; // stop looping
          });
    
          // Update 'CompletionStatus' with new value (using update() to protect existing data)
          // Remember to return the promise
          return firstResultRef.update({ CompletionStatus: status });
        })
        .then(() => { // Promise.then(successHandlerFunc, errorHandlerFunc)
          // success
          agent.add("Status has been changed to " + status);
        }, (err) => {
          // failure
          if (err === RESULT_NOT_FOUND) {
            agent.add("Sorry, I couldn't find '" + chosenHw + "'.");
          } else if (err === RESULT_DUPLICATED) {
            agent.add("Sorry, I found multiple files that match '" + chosenHw + "'.");
          } else {
            // if here, a database error has occurred.
            agent.add("Sorry, I could not process that request at this time.");
            // TODO: Log error "err".
          }
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2017-08-22
      • 2017-07-17
      • 2016-12-30
      • 2010-10-30
      • 2017-10-11
      • 2019-08-07
      • 2013-05-28
      • 1970-01-01
      • 2021-07-07
      相关资源
      最近更新 更多