当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);
}
例如(我附上了我的Firebase图片)
Dialogflow:您要更改的作业的名称是什么 完成状态? (我已经做到了)
,并且当用户说“ Coding Worksheet 7”和所需状态为“是”时, 具体数据将被更改。 (此编码部分需要使用hep。)
因此,预期结果将是“ Coding Worksheet 7”的CompletionStatus更改为“ No”。
答案 0 :(得分:2)
当前解决方案的关键问题是Firebase RT Database调用是异步的,并且在响应用户之前,您不必等待这些调用返回结果。
此外,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".
}
});
}