Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

firebase on('value') with await does not work as expected

I'm looking to build function to wait until all values in on('value') will be set and then go to the next line, in other words async function.

 let upcomingGamesList = await firebase.database().ref('UpcomingGames').on('value', snapshot => {
        upcomingGamesList = snapshot.val()
        console.log('upcoming t1',upcomingGamesList)
        return upcomingGamesList
    })
    console.log('upcoming t2',upcomingGamesList)
    let upcomingPreferences = upcomingGamesList.map(async(game) => {
        console.log(game)
        let GameId = game.GameId
        await firebase.database().ref(`GameNotificationPreferances/${GameId}`).orderByKey().equalTo(UserStore.user.uid).once('value', snapshot => {
            if (snapshot.val() != null || snapshot.val() != undefined) {
                conosle.log(snapshot.val())
            } else {
                console.log('not value')
            }
        })
        console.log(game)
    })

what that happened is the upcoming t2

        console.log('upcoming t2',upcomingGamesList)

is printed before upcoming t1

    console.log('upcoming t2',upcomingGamesList)

But I used await in this function

  let upcomingGamesList = await firebase.database().ref('UpcomingGames').on('value', snapshot => {
        upcomingGamesList = snapshot.val()
        console.log('upcoming t2',upcomingGamesList)
        return upcomingGamesList
    })

and it should wait until it finish and then go to next line

I want to wait until the function will finish and then get the updatedList with the change i did

 let upcomingGamesList = await firebase.database().ref('UpcomingGames').on('value', async(snapshot) => {
        upcomingGamesList = snapshot.val()
        updatededList = await upcomingGamesList.map(async(game) => {
            let GameId = game.GameId
            await firebase.database().ref(`GameNotificationPreferances/${GameId}`).orderByKey().equalTo(UserStore.user.uid).once('value', async(snapshot) => {
                if (snapshot.val() != null || snapshot.val() != undefined) {
                    game['reminderPressed'] = true;
                } else {
                    game['reminderPressed'] = false
                }
                console.log('GameId:',GameId, 'GameDetails:',game)
                return ({...game})

            })

        })


    })
    console.log('the updatedList is',updatededList)
like image 271
Manspof Avatar asked May 23 '18 18:05

Manspof


1 Answers

Firebase's on() function will continuously listen to the location that you call them on. That means that they can give you data multiple times. Since a Promise can only resolve once, on() does not return a promise. And thus it can't be used with async/await.

In this case it looks like you'll want to use once(), which works pretty much the same but will only deliver a result once (and thus returns a promise):

let upcomingGamesList = await firebase.database().ref('UpcomingGames').once('value', snapshot => {
    upcomingGamesList = snapshot.val()
    console.log('upcoming t2',upcomingGamesList)
    return upcomingGamesList
})
like image 73
Frank van Puffelen Avatar answered Sep 20 '22 19:09

Frank van Puffelen