从循环中的firebase云函数异步调用中收集结果

时间:2018-03-16 20:41:22

标签: javascript firebase google-cloud-functions

我试图在循环中查询firebase数据,然后我需要从那里收集数据创建数据集合并返回调用函数。

以下是我的代码,我无法收集结果并在数组中收集所有结果之前执行return语句。

function xyz() {
    ...
    // variable lookupKey is defined above this function
    return dbRef.child(`/location/${lookupKey}`).once('value').then(contacts => {
        const otherUserNotificationids = []
        contacts.forEach(function(element) {
            var id = element.val()
            console.log(`found id: ${id}`)
            dbRef.child(`/tokenLookup/${id}`).once('value').then(notifId => {
                const nVal = notifId.val()
                console.log(`found notification id : ${nVal}`)
                otherUserNotificationids.push(nVal)
            })
        });
        const len = otherUserNotificationids.length
        console.log(`found notificationIds count : ${len}`)
        return Promise.all([otherUserNotificationids])
    })
}

正如预期的那样,该功能完成后发现notificationIds计数:0',

如何从/ tokenLookup / $ {id}调用中收集结果并从中创建一个集合。

我这样做,所以我不必为每个令牌调用admin.messasing()。sendToDevice(),而是我可以用一个数组调用它一次到令牌并完成它。

在Doug的回复之后,我认真思考了我对Promises的使用,这就是我如何解决它:

function xyz() {
   //moved this variable to top of function (rather then inner scope)
   const otherUserNotificationids = []    
    ...
    // variable lookupKey is defined above this function
    return dbRef.child(`/location/${lookupKey}`).once('value').then(contacts => {
        const promises = []
        contacts.forEach(function(element) {
            var id = element.val()
            console.log(`found id: ${id}`)
            const prms = dbRef.child(`/tokenLookup/${id}`).once('value').then(notifId => {
                const nVal = notifId.val()
                console.log(`found notification id : ${nVal}`)
                otherUserNotificationids.push(nVal)
            })
            promises.push(prms)
        });
        return Promise.all(promises).then(res => {
        const len = otherUserNotificationids.length
        console.log(`found notificationIds count : ${len}`)
        return Promise.all([otherUserNotificationids])
        })
    })
}

1 个答案:

答案 0 :(得分:2)

此调用是异步的,并立即返回:

dbRef.child(`/tokenLookup/${id}`).once('value').then(...)

在返回数组otherUserNotificationids之前,你并没有等到它完成。

此外,您似乎对传递给Promise.all()的内容产生了误解。 Promise.all()接受一系列承诺,在解决它返回的承诺之前等待,这不是你正在做的事情。

应该做的是收集重复调用once()返回到数组中的所有promise,将数组传递给Promise.all(),然后在返回的promise解析后,处理所有快照在回调中可用。