【问题标题】:Working with HTTPS request and async functions to database using TypeScript使用 TypeScript 处理对数据库的 HTTPS 请求和异步函数
【发布时间】:2019-01-27 11:44:42
【问题描述】:

我正在尝试使用实时数据库创建我的第二个 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(第一个节点获得一个元素,第二个节点获得两个元素,第三个节点获得三个。 ..)

有人知道我在哪里搞砸了吗?

【问题讨论】:

  • 不要使用on() 方法,并为初始数据触发回调,并在数据更改时再次触发,您应该使用once() 方法,请参阅firebase.google.com/docs/reference/node/…
  • 好的。但是如果我的数据是时间相关的呢?它应该在每小时结束时处理。
  • 要在每小时结束时处理它,您应该使用像cron-job.org/en这样的外部服务来调用HTTPS云函数
  • 是的,这就是我想要做的。我刚刚从您的回答中实施了您的建议,谢谢,会告诉您进展如何。
  • 请不要进一步回滚编辑,CodingCaio。您是打字稿的新手与问题无关

标签: typescript firebase firebase-realtime-database google-cloud-functions


【解决方案1】:

我在您的代码中发现了几个可能存在问题的区域:

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()

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(...)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-10
    • 2020-07-21
    • 1970-01-01
    • 2012-05-20
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    相关资源
    最近更新 更多