Node.js firebase函数在完成代码处理之前返回

Node.js firebase函数在完成代码处理之前返回,node.js,firebase,firebase-realtime-database,google-cloud-functions,Node.js,Firebase,Firebase Realtime Database,Google Cloud Functions,我有一个低于火基的触发器 exports.on_order_received_deduct_doodle_cash = functions.database.ref("/orders/{id}") .onCreate((snapshot, context) => { console.log("start of on_order_received_deduct_doodle_cash") const order = snapshot.val();

我有一个低于火基的触发器

exports.on_order_received_deduct_doodle_cash = functions.database.ref("/orders/{id}")
    .onCreate((snapshot, context) => {
      console.log("start of on_order_received_deduct_doodle_cash")   

      const order = snapshot.val();
      const customerObj = order.customer
      const orderObj = order.order

      const paymentType = orderObj._paymentType
      console.log("payment type is::" + paymentType)

      if(paymentType === 'DoodleCash'){
        console.log("payment type is DoodleCash so deduct it from customer account")
        const afterDiscount = orderObj._afterDiscount
        const uid = customerObj._uid

        console.log("Customer uid is::" + uid)
        var db = admin.database();
        const userRef = db.ref('users/')
        userRef.child(uid).once("value").then(
            (resp) => {

                console.log("user value:" + JSON.stringify(resp))
                const userObj = resp.val()
                  let doodleCash = userObj._doodleCash
                  console.log("user current doodle cash is::" + doodleCash)
                  if(doodleCash === undefined)
                     doodleCash = 0

                  if(doodleCash > afterDiscount){
                    const val = doodleCash - afterDiscount

                    console.log("new doodle cash will be:" + val)
                    return userRef.child(uid).update({"_doodleCash" : val})
                  }else{
                        console.error("cannot be a negative value")
                        return null
                    }
            }
        ).catch(
            (err) =>  {
                            console.error("something went wrong:" + err)
                            return null
                     }
            )
      }else{
          return null
      }
})
这是一个执行过程,我可以看到方法在userRef.childuid.oncevalue完成之前完成。为什么?或者如何修复?我相信我的代码应该是阻塞的,然后等待它完成触发器。我是不是遗漏了什么?请告知

2:25:44.698 AM
on_order_received_deduct_doodle_cash
something went wrong:TypeError: Cannot read property '_doodleCash' of null

2:25:44.698 AM
on_order_received_deduct_doodle_cash
user value:null

2:25:36.406 AM
on_order_received_deduct_doodle_cash
Function execution took 618 ms, finished with status: 'ok'

2:25:36.198 AM
on_order_received_deduct_doodle_cash
Function returned undefined, expected Promise or value

2:25:35.796 AM
on_order_received_deduct_doodle_cash
Customer uid is::3jwWMscY4mZGATQZg94d7wyRE143

2:25:35.796 AM
on_order_received_deduct_doodle_cash
payment type is DoodleCash so deduct it from customer account

2:25:35.796 AM
on_order_received_deduct_doodle_cash
payment type is::DoodleCash

2:25:35.788 AM
on_order_received_deduct_doodle_cash
Function execution started

正如您将在Firebase视频系列中关于JavaScript承诺的三个官方Firebase视频中看到的,对于由事件触发的云函数,您必须在云函数中返回一个承诺或一系列承诺,以向平台表明所有异步工作都已完成

如果您不这样做,平台可能会停止执行您的云功能,这显然是发生在您身上的事情

因此,您应该对代码进行如下调整:

exports.on_order_received_deduct_doodle_cash = functions.database.ref("/orders/{id}")
    .onCreate((snapshot, context) => {
        console.log("start of on_order_received_deduct_doodle_cash")

        const order = snapshot.val();
        const customerObj = order.customer
        const orderObj = order.order

        const paymentType = orderObj._paymentType
        console.log("payment type is::" + paymentType)

        if (paymentType === 'DoodleCash') {
            console.log("payment type is DoodleCash so deduct it from customer account")
            const afterDiscount = orderObj._afterDiscount
            const uid = customerObj._uid

            console.log("Customer uid is::" + uid)
            var db = admin.database();
            const userRef = db.ref('users/')
            return userRef.child(uid).once("value")  // <- Note the return here
            .then(resp => {

                    console.log("user value:" + JSON.stringify(resp))
                    const userObj = resp.val()
                    let doodleCash = userObj._doodleCash
                    console.log("user current doodle cash is::" + doodleCash)
                    if (doodleCash === undefined) {
                        doodleCash = 0
                    }
                    if (doodleCash > afterDiscount) {
                        const val = doodleCash - afterDiscount

                        console.log("new doodle cash will be:" + val)
                        return userRef.child(uid).update({ "_doodleCash": val })
                    } else {
                        console.error("cannot be a negative value")
                        return null
                    }
            })
            .catch(
                (err) => {
                    console.error("something went wrong:" + err)
                    return null
                }
            )
        } else {
            return null
        }
    })

正如您将在Firebase视频系列中关于JavaScript承诺的三个官方Firebase视频中看到的,对于由事件触发的云函数,您必须在云函数中返回一个承诺或一系列承诺,以向平台表明所有异步工作都已完成

如果您不这样做,平台可能会停止执行您的云功能,这显然是发生在您身上的事情

因此,您应该对代码进行如下调整:

exports.on_order_received_deduct_doodle_cash = functions.database.ref("/orders/{id}")
    .onCreate((snapshot, context) => {
        console.log("start of on_order_received_deduct_doodle_cash")

        const order = snapshot.val();
        const customerObj = order.customer
        const orderObj = order.order

        const paymentType = orderObj._paymentType
        console.log("payment type is::" + paymentType)

        if (paymentType === 'DoodleCash') {
            console.log("payment type is DoodleCash so deduct it from customer account")
            const afterDiscount = orderObj._afterDiscount
            const uid = customerObj._uid

            console.log("Customer uid is::" + uid)
            var db = admin.database();
            const userRef = db.ref('users/')
            return userRef.child(uid).once("value")  // <- Note the return here
            .then(resp => {

                    console.log("user value:" + JSON.stringify(resp))
                    const userObj = resp.val()
                    let doodleCash = userObj._doodleCash
                    console.log("user current doodle cash is::" + doodleCash)
                    if (doodleCash === undefined) {
                        doodleCash = 0
                    }
                    if (doodleCash > afterDiscount) {
                        const val = doodleCash - afterDiscount

                        console.log("new doodle cash will be:" + val)
                        return userRef.child(uid).update({ "_doodleCash": val })
                    } else {
                        console.error("cannot be a negative value")
                        return null
                    }
            })
            .catch(
                (err) => {
                    console.error("something went wrong:" + err)
                    return null
                }
            )
        } else {
            return null
        }
    })

快速问题:注意内部返回userRef.childuid.update{{u doodleCash:val}好吗?我在某个地方读到过,你刚才建议不要等待内部返回userRef.chid。。。要完成吗?是的,在第一时间内回复承诺是可以的。这实际上是链接承诺的方法,请参见和。快速问题:注意内部返回userRef.childuid.update{u doodleCash:val}它好吗?我在某个地方读到过,你刚才建议不要等待内部返回userRef.chid。。。要完成吗?是的,在第一时间内回复承诺是可以的。这实际上是连锁承诺的方式,请参见和。