我有这个密码
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")
}
})
简单来说,这段代码的作用是通过while循环计算玩家的生命值和对怪物造成的伤害。这是正确的。问题是当我想把result变量中的数据发送给用户做进一步的工作时。它每次都返回null。你知道错误在哪里吗?我唯一能想到的是错误应该在返回中。也许在请求的数据有任何价值之前它就被调用了。我不知道。我想不通。
但是我确信我想发送给用户的值不是null,而是应该具有的值。
Firebase console log
这是我用于客户端返回的代码。我总是在这里得到null
var battle = firebase.functions().httpsCallable('battle')
battle().then(result => {
console.log(result)
})
- 更新:**Frank的回答是很好的指导。但我不认为它是完全清楚的。经过更长的搜索,我在这里找到了一个更容易理解的解决方案:https://medium.com/@stephane.giron/firebase-cloud-functions-oncall-returned-before-end-of-the-function-2d898d8ff259
我只是在代码的开头更改了此内容,并在结尾添加了此内容
exports.battle = functions.https.onCall((data, context) => {
if(context.auth){
return new Promise(function(resolve, reject) {
/*
. . . .
code
. . . .
*/
reslove(result)
)}
我建议在代码末尾添加.catch
以防止可能出现的错误,但我不完全确定,所以我不想混淆
1条答案
按热度按时间lb3vh1jj1#
Promises的结果会出现在调用者那里,但前提是你必须在
then
或catch
回调中返回它们。因此,在每个once
回调中,你都需要确保将值return
返回给调用者。首先,您在顶级Cloud函数中缺少一个顶级
return
语句,这意味着您的return result
永远不会到达调用方。因此:
接下来,您需要对
ref.child("level").once("value", (snapshot) => {
和其他单个once
调用执行相同的操作。最后,如果您有一个循环,其中您对循环中的每个项目执行异步作业(例如
once
或update
),您可以使用Promise.all
来等待所有这些作业完成,然后再完成作业并将值传回呼叫端。我建议阅读MDN上Using Promises中的承诺,terminating functions: sync, async and promises上的Firebase文档,并观看那里链接的Doug的优秀视频系列。
不相关,但此代码比所需的复杂得多:
Firebase实时数据库现在有一个内置的
increment
操作,这意味着您可以将其简化为: