Javascript 嵌套承诺中超过Firebase云函数截止日期错误
我有一个firebase云函数无法完成执行。我怀疑我的代码可以显著改进,但我不太确定如何改进 我已经尽可能具体地进行了查询,试图减少迭代所需的文档数量,但这并没有解决问题 我得到了一个超过截止日期的错误,我怀疑这是由于我正在迭代这么多文档并试图更新它们 我在谷歌云控制台中增加了超时(9分钟)和内存分配(2GB),但这也没有帮助Javascript 嵌套承诺中超过Firebase云函数截止日期错误,javascript,node.js,firebase,google-cloud-platform,Javascript,Node.js,Firebase,Google Cloud Platform,我有一个firebase云函数无法完成执行。我怀疑我的代码可以显著改进,但我不太确定如何改进 我已经尽可能具体地进行了查询,试图减少迭代所需的文档数量,但这并没有解决问题 我得到了一个超过截止日期的错误,我怀疑这是由于我正在迭代这么多文档并试图更新它们 我在谷歌云控制台中增加了超时(9分钟)和内存分配(2GB),但这也没有帮助 exports.updatePollWinner = functions.runWith(runtimeOpts).firestore.document('trigger
exports.updatePollWinner = functions.runWith(runtimeOpts).firestore.document('triggerAccuracyCalculation/{id}').onCreate(trigger => {
const week = trigger.get('week');
const scoringTags = ["STD", "0.25PPR", "0.5PPR", "PPR", "0.10PPC", "0.25PPC", "0.5PPC", "4PTPASS", "5PTPASS", "6PTPASS", "-2INT", "TEPREMIUM"]
let winningChoiceIds = [];
let totalPollIds = [];
return db.collection("polls").where("sport", "==", 1).where("week", "==", week).where("pollType", "==", "WDIS").get()
.then((querySnapshot) => {
console.log("A");
querySnapshot.forEach((doc) => {
totalPollIds.push(doc.id);
let pollData = doc.data();
// extract relevant scoring tags
let tags = pollData.tags.filter(tag => scoringTags.includes(tag.code)).map(tag => tag.code);
// if no scoring setting is tagged, then use STD - determine what STD is
// extract player from each option
let winner = {score: 0, choice: {}, choiceId: null};
let cnt = 0;
pollData.choices.forEach((choice) => {
let choiceId = choice.id
let mappedChoices = choice.players.map(player => {
return { displayName: player.displayName, playerId: player.playerId, position: player.position, team: player.team }
});
// ToDo: What happens if someone posts a poll with two players in one option? This poll should be ignoree from accuracy calculation
// ignmore if option has more than one player
// if (mappedChoices.length > 1) return;
const player = mappedChoices[0]
// We can't score defense
if (player.position === "DEF") {
return;
}
const playerId = player.playerId;
// Make FFN API call to retrieve stats for that player in that weekconst statsEndpoint = `https://www.fantasyfootballnerd.com/service/player/json/${functions.config().ffnerd.key}${req.url}`;
const statsEndpoint = `https://www.fantasyfootballnerd.com/service/player/json/${functions.config().ffnerd.key}/${playerId}`;
const json = {"Stats": {"2019": ""}, "Player": {}};
https.get(statsEndpoint, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
const weekString = week.toString();
const fetchedStats = JSON.parse(data).Stats
if (!fetchedStats) return;
const response = fetchedStats["2019"]
if (!response) return;
// TODO SCORE KICKERS AND DEFENSES
const stats = response[weekString];
let score = 0;
stats["recYards"] ? score += parseInt(stats["recYards"]) / 10 : false
stats["recTD"] ? score += parseInt(stats["recTD"]) * 6 : false
stats["rushYards"] ? score += parseInt(stats["rushYards"]) / 10 : false
stats["rushTD"] ? score += parseInt(stats["rushTD"]) * 6 : false
stats["xpMade"] ? score += parseInt(stats["xpMade"]) : false
stats["fgMade"] ? score += parseInt(stats["fgMade"]) * 3 : false
stats["kickoffRet"] ? score += parseInt(stats["kickoffRet"]) / 10 : false
stats["SackYards"] ? score -= parseInt(stats["SackYards"]) / 10 : false
stats["fumbleLost"] ? score -= parseInt(stats["fumbleLost"]) * 2 : false
// Determine winner
// ToDo: handle ties
if (score > winner.score) {
winner.score = score;
winner.choiceId = choiceId;
winner.choice = choice;
}
if (cnt>=pollData.choices.length-1){
// Save player object on the poll Document (include choice ID)
winningChoiceIds.push(winner.choiceId);
const pollDoc = db.doc(`polls/${doc.id}`);
pollDoc.update({winner: winner});
}
cnt++;
});
}).on("error", (err) => {
console.log("Error: ", err.message);
});
});
});
console.log("B");
return false;
}).then(() => {
console.log("C");
let dateToQueryAfter = new Date(new Date("08/22/19").setHours(0,0,0,0))
return db.collection("users").where("recentVote", ">", dateToQueryAfter).get()
})
.then((querySnapshot) => {
console.log("D");
const promises = [];
querySnapshot.forEach((doc) => {
const p = db.collection("votes").where("uid", "==", doc.id).where("week", "==", week).where("pollType", "==", "WDIS").get()
promises.push(p)
});
return Promise.all(promises)
})
.then((querySnapshots) => {
console.log("E");
querySnapshots.forEach((querySnapshot) => {
if (querySnapshot.docs.length <= 0) return;
const uid = querySnapshot.docs[0].data().uid
const retrieveUserDoc = db.doc(`users/${uid}`);
let correctVotes = 0;
let cnt = 0;
let totalVotes = 0;
let pollVoteIds = [];
let pollVoteIdsCorrect = [];
querySnapshot.docs.forEach((doc) => {
const voteData = doc.data();
if (totalPollIds.includes(voteData.poll)) {
pollVoteIds.push(voteData.poll)
totalVotes++;
if (winningChoiceIds.includes(voteData.choice)) {
pollVoteIdsCorrect.push(voteData.poll)
correctVotes++;
}
}
if (cnt>=querySnapshot.size-1){
console.log("Updating user ID: ", uid);
retrieveUserDoc.update({
['accuracyWeeks.week'+week]: true,
['accuracy.week'+week]: {
totalVotes: totalVotes,
correct: correctVotes,
accuracy: correctVotes/totalVotes,
correctVoteIds: pollVoteIdsCorrect,
totalVoteIds: pollVoteIds
}
});
}
cnt++;
})
});
console.log("F");
return false;
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
});
exports.updatePollWinner=functions.runWith(runtimeOpts.firestore.document('triggeracycalculation/{id}')。onCreate(trigger=>{
const week=trigger.get('week');
const scoringTags=[“标准”、“0.25PPR”、“0.5PPR”、“PPR”、“0.10PPC”、“0.25PPC”、“0.5PPC”、“4tpass”、“5tpass”、“6PTPASS”、“-2INT”、“TEPREMIUM”]
让WinningChoiceId=[];
设totalPollIds=[];
返回db.collection(“polls”).where(“sport”、“==”,1).where(“week”、“==”,week).where(“pollType”、“==”、“WDIS”).get()
.然后((querySnapshot)=>{
控制台日志(“A”);
querySnapshot.forEach((doc)=>{
totalPollIds.push(doc.id);
设pollData=doc.data();
//提取相关的评分标签
让tags=pollData.tags.filter(tag=>scoringTags.includes(tag.code)).map(tag=>tag.code);
//如果没有标记评分设置,则使用标准-确定标准是什么
//从每个选项中提取玩家
让获胜者={score:0,choice:{},choiceId:null};
设cnt=0;
pollData.choices.forEach((choice)=>{
让choiceId=choice.id
让mappedChoices=choice.players.map(player=>{
return{displayName:player.displayName,playerId:player.playerId,position:player.position,team:player.team}
});
//ToDo:如果有人在一个选项中发布了两名参与者的投票结果,会发生什么情况?该投票结果应忽略准确性计算
//如果选项有多个玩家,则忽略此选项
//如果(mappedChoices.length>1)返回;
const player=mappedChoices[0]
//我们不能得分防守
如果(player.position==“DEF”){
返回;
}
const playerId=player.playerId;
//进行FFN API调用以检索该玩家在该周的统计数据CONST statsEndpoint=`https://www.fantasyfootballnerd.com/service/player/json/${functions.config().ffnerd.key}${req.url}`;
常数statsEndpoint=`https://www.fantasyfootballnerd.com/service/player/json/${functions.config().ffnerd.key}/${playerId}`;
const json={“Stats”:{“2019”:“}”,Player:{};
https.get(statsEndpoint,(resp)=>{
让数据=“”;
在('数据',(块)=>{
数据+=块;
});
分别在('结束',()=>{
const weekString=week.toString();
const fetchedStats=JSON.parse(data).Stats
如果(!fetchedStats)返回;
const response=fetchedStats[“2019”]
如果(!响应)返回;
//TODO得分踢球者和防守
const stats=响应[周字符串];
分数=0;
统计数据[“记录”]?分数+=parseInt(统计数据[“记录”])/10:false
统计数据[“recTD”]?分数+=parseInt(统计数据[“recTD”])*6:false
统计数据[“rushYards”]?分数+=parseInt(统计数据[“rushYards”])/10:false
统计数据[“rushTD”]?分数+=parseInt(统计数据[“rushTD”])*6:false
统计数据[“xpmake”]?分数+=parseInt(统计数据[“xpmake”]):false
统计数据[“fgmake”]?分数+=parseInt(统计数据[“fgmake”])*3:false
统计数据[“kickoffRet”]?分数+=parseInt(统计数据[“kickoffRet”])/10:false
统计数据[“SackYards”]?得分-=parseInt(统计数据[“SackYards”])/10:false
统计数据[“失意”]?分数-=parseInt(统计数据[“失意”])*2:false
//决胜
//待办事项:处理领带
如果(分数>赢家分数){
winner.score=分数;
winner.choiceId=choiceId;
胜者。选择=选择;
}
if(cnt>=pollData.choices.length-1){
//在投票文档上保存玩家对象(包括选项ID)
WinningChoiceId.push(winner.choiceId);
const pollDoc=db.doc(`polls/${doc.id}`);
更新({winner:winner});
}
cnt++;
});
}).on(“错误”,(错误)=>{
日志(“错误:”,错误消息);
});
});
});
控制台日志(“B”);
返回false;
}).然后(()=>{
控制台日志(“C”);
let dateToQueryAfter=新日期(新日期(“08/22/19”)。设定小时数(0,0,0,0))
返回db.collection(“users”).where(“recentVote”,“>”,dateToQueryAfter.get()
})
.然后((querySnapshot)=>{
控制台日志(“D”);
常量承诺=[];
querySnapshot.forEach((doc)=>{
const p=db.collection(“投票”).where(“uid”,“doc.id”).where(“week”,“week”).where(“pollType”,“WDIS”).get()
承诺推送(p)
});
回报承诺。全部(承诺)
})
.然后((querySnapshots)=>{
控制台日志(“E”);
querySnapshot.forEach((querySnapshot)=>{
if(querySnapshot.docs.length{
const voteData=doc.data();
if(totalPollIds.includes(voteData.poll)){
pollVoteIds.push(voteData.poll)
总票数++;
if(WinningChoiceId.includes(voteData.choice)){
pollVoteIdsCorrect.push(voteData.poll)
正确的投票++;
}
}
如果(cnt>=querySnapshot.size-1){
欺骗