我正在尝试使用实时数据库创建第二个Firebase函数。想法是接收HTTPS请求,然后该函数在名为 buffer 的节点上获取数据,然后处理所有这些数据,将其推入名为 history 的节点,然后删除从缓冲区处理的数据。我认为promises
做错了。
这是我到目前为止所拥有的:
export const processBuffer = functions.https.onRequest( (request, response) => {
const refBuffer = admin.database().ref('/buffer')
refBuffer.on('value', ( dataSnapShot ) => {
const promises = []
const snapshot = dataSnapShot.val()
for( const id in snapshot ) {
// Processs data in the buffer
let keys = []
...
let promise = admin.database().ref('/history').child(id).push().set({ timestamp: timestamp, value: value } )
.then( (e) => {
keys.forEach( key => {
let p = admin.database().ref('/buffer').child(id).child(key).remove()
promises.push(p)
})
return Promise.all(promises)
})
}
response.send("Ok")
})
})
如果不从缓冲区中删除节点,它将按预期工作。但是如果我这样做,无论出于何种原因,它都会弄乱我的历史节点。例如,如果缓冲区中有3个元素,则处理后历史上应该有3个元素。当我不从缓冲区中删除元素时,此方法有效,但是当我尝试删除这些节点时,它们在历史记录中的乘数为1(第一个节点获取一个元素,第二个节点获取两个元素,第三个节点获取三个元素)。 ..)
有人知道我在搞砸吗?
答案 0 :(得分:2)
我在您的代码中看到了一些可能存在问题的区域:
1 /应该使用on()
方法,而不是使用once()
方法,并且要对初始数据触发回调,并在数据更改时再次触发回调,请参见:https://firebase.google.com/docs/reference/node/firebase.database.Reference#once
2 / Promise.all()
调用应在for( const id in snapshot )
循环之外:想法是填充promises
数组,并在完全填充之后,调用Promise.all()
< / p>
3 /您不应在循环中多次调用admin.database().ref('/history').child(id).push().set()
。使用update()
方法(请参阅doc),该方法允许“一次将多个值写入数据库”。
4 /您还应该等待Promise.all(promises)
解析后再返回响应,如下所示:
....
for( const id in snapshot ) {
//populate the promises array
}
return Promise.all(promises)
})
.then((result) => {
response.send("Ok")
})
.catch(...)