2022-11-25

Returning data from firebase functions returns null

I have this code

exports.battle = functions.https.onCall((data, context) => {
    if(context.auth){
        var difficulty = randInt(2,10) / 10
        var user = context.auth["uid"]
        
        var userHP
        var userLevel
        var userDmg 
        var resultUserDmg = []
        var resultUserHp = []

        var monsterHP
        var monsterLevel
        var monsterDmg
        var resultMonsterDmg = []
        var resultMonsterHp = []

        

        var ref = db.ref(`players/${user}`);
        ref.child("hp").once("value", (snapshot) => {
           userHP = snapshot.val()
           monsterHP = userHP * difficulty

           ref.child("level").once("value", (snapshot) => {
                userLevel = snapshot.val()
                monsterLevel = userLevel * difficulty

                console.log("type"+typeof(userHP))
                console.log("value"+userHP)
                

                console.log("type"+typeof(monsterHP))
                console.log("value"+monsterHP)
                console.log("diff "+difficulty)


                while (userHP > 0 && monsterHP > 0){
                    userDmg = randInt(7, 14) * userLevel
                    monsterDmg = randInt(7, 14) * userLevel * difficulty


                    userHP = Math.round((userHP - monsterDmg)*10) /10;
                    console.log("userHP"+(userHP))
                    console.log("monsterDmg"+monsterDmg)
                    resultMonsterDmg.push(Math.round(monsterDmg*10) /10)
                    resultUserHp.push(Math.round(userHP*10)/10)
                    monsterHP = Math.round((monsterHP - userDmg)*10) /10;
                    console.log("userDmg"+userDmg)
                    console.log("monsterHP"+monsterHP)
                    resultUserDmg.push(Math.round(userDmg*10)/10)
                    resultMonsterHp.push(Math.round(monsterHP*10)/10)
                    console.log("----------")
                }

            
                var ref = db.ref(`players/${user}/coins`);
                ref.once("value", function(snapshot) {
                    var coinsNow = parseInt(snapshot.val());
                    const userRef = db.ref(`players/${user}`);
                    userRef.update({
                        'coins' : coinsNow+1
                    })
                });

                var result ={
                    userDmg : resultUserDmg,
                    userHp : resultUserHp,
                    monsterDmg : resultMonsterDmg,
                    monsterHp : resultMonsterHp,
                    monsterLvl : monsterLevel,
                };
                console.log("result is "+resultUserDmg)
                console.log("result is "+resultUserHp)
                console.log("result is "+resultMonsterDmg)
                console.log("result is "+resultMonsterHp)
                console.log("result is "+monsterLevel)
                return result 

            })
        })
    }
    else{
        console.log("User is not logged")
    }

    
})

Simply what this code does is that it calculates the player's life and damage against the monster using a while loop. This works correctly. The problem is when I want to send the data in the result variable to the user for further work. It returns null every time. Do you know where the error is? The only thing I can think of is that the error would be in the return. Maybe it gets called before the requested data has any value. I don't know. I can't figure it out.

But I am sure that the values I want to send to the user are not null but have the values they should have. Here is the log from the firebase console

Firebase console log

Here is code that i am useing for client returning. I always get null here

var battle = firebase.functions().httpsCallable('battle')
    battle().then(result => {
        console.log(result)
    })

UPDATE: Frank's response was great direction. But I don't think it's entirely clear. After a longer search, I found a more understandable solution for me here: https://medium.com/@stephane.giron/firebase-cloud-functions-oncall-returned-before-end-of-the-function-2d898d8ff259

I simply changed this at the beginning of the code ann add this to the end

exports.battle = functions.https.onCall((data, context) => {
    if(context.auth){
         return new Promise(function(resolve, reject) {
                
                 /* 
                   . . . .                       
                     code 
                   . . . .
                            */

                 reslove(result)
)}

I hope this has helped someone else. I recommend adding .catch to the end of the code for possible errores but I'm not entirely sure so I don't want to possibly confuse



No comments:

Post a Comment