如何为Firebase函数编写正确的promise,该函数使用Axios查询外部API,并将JSON响应保存在多个Fir



如果我的第一个问题能得到一些帮助,我会很高兴。我是一名安卓开发人员,目前正在做一个需要Firebase云功能的项目,我是新手。我正在使用Axios调用外部API,并将JSON响应保存到多个Firestore文档中。在我调用该函数的5次中,有4次执行时没有出错,但它没有写入Firestore,而在1次写入Firestore时,写入数据需要8到12秒。

我读了一些关于promise的文章,并应用了该函数(据我所知(,但问题仍然存在。请让专家告诉我我做错了什么。下面是我的云功能:

const functions = require("firebase-functions");
const axios = require("axios");
const admin = require("firebase-admin");
const api_token = "---------";
const includes = "------------";
const url = "------------" + api_token + includes;
exports.liveScores = functions.https.onRequest((req, res) => {
return axios.get(url)
.then(response => {
var data  = response.data.data;
data.forEach(function(obj){
admin.firestore().collection("fixtures").doc(obj.id.toString()).set({
id : obj.id,
league_id : obj.league_id,
venue : obj.venue_id,
localteam_id : obj.localteam_id,
visitorteam_id : obj.visitorteam_id,
round_id : obj.round_id,
round_name : obj.round ?  obj.round.data.name : null,
stage_id : obj.stage_id,
localteam_score : obj.scores.localteam_score,
visitorteam_score : obj.scores.visitorteam_score,
status : obj.time.status,
timestamp : new admin.firestore.Timestamp(obj.time.starting_at.timestamp, 0),
real_date : obj.time.starting_at.date,
minute : obj.time.minute,
injury_time : obj.time.injury_time,
localteam_formation : obj.formations.localteam_formation,
visitorteam_formation : obj.formations.visitorteam_formation,
visitorTeam : obj.visitorTeam.data.name,
localTeam : obj.localTeam.data.name,
local_team_logo : obj.localTeam.data.logo_path,
visitor_team_logo : obj.visitorTeam.data.logo_path,
season_id : obj.season_id,
referee : obj.referee ? obj.referee.data.fullname : null,
aggregate : obj.aggregate ? obj.aggregate.data.result : null,
venue_name : obj.venue && obj.venue.data.name ? obj.venue.data.name : null,
weather_type : obj.weather_report && obj.weather_report.type ? obj.weather_report.type : null,
weather_icon : obj.weather_report && obj.weather_report.icon ? obj.weather_report.icon : null,
temperature : obj.weather_report && obj.weather_report.temperature_celcius ?         obj.weather_report.temperature_celcius.temp : null
}).then(() => {
console.log("Fixtures table complete...");
})

var no_of_events = obj.events.data.length;
for(var i=0; i < no_of_events; i++ ){
admin.firestore().collection("events").doc(obj.events.data[i].fixture_id.toString()).collection("all_events").doc(obj.events.data[i].id.toString()).set({
type : obj.events.data[i].type,
team_id : obj.events.data[i].team_id,
fixture_id : obj.events.data[i].fixture_id,
var_result : obj.events.data[i].var_result,
player_id : obj.events.data[i].player_id,
player_name : obj.events.data[i].player_name,
related_player_id : obj.events.data[i].related_player_id,
related_player_name : obj.events.data[i].related_player_name,
minute : obj.events.data[i].minute,
reason : obj.events.data[i].reason,
id : obj.events.data[i].id
}).then(() => {
console.log("Events table complete...");
})
}
for(var y=0; y < obj.lineup.data.length; y++){
admin.firestore().collection("lineup").doc(obj.lineup.data[y].fixture_id.toString()).collection("lineup").doc(obj.lineup.data[y].player_id.toString()).set({
fixture_id : obj.lineup.data[y].fixture_id,
team_id : obj.lineup.data[y].team_id,
player_id : obj.lineup.data[y].player_id,
player_name : obj.lineup.data[y].player_name,
number : obj.lineup.data[y].number,
position : obj.lineup.data[y].position,
formation_position : obj.lineup.data[y].formation_position,
captain : obj.lineup.data[y].captain
}).then(() => {
console.log("Lineup table complete...");
})
}
for(var x=0; x < obj.bench.data.length; x++){
admin.firestore().collection("bench").doc(obj.bench.data[x].fixture_id.toString()).collection("bench").doc(obj.bench.data[x].player_id.toString()).set({
fixture_id : obj.bench.data[x].fixture_id,
team_id : obj.bench.data[x].team_id,
player_id : obj.bench.data[x].player_id,
player_name : obj.bench.data[x].player_name,
number : obj.bench.data[x].number,
position : obj.bench.data[x].position,
formation_position : obj.bench.data[x].formation_position,
captain : obj.bench.data[x].captain
}).then(() => {
console.log("Bench table complete...");
})
}
for(var c=0; c < obj.stats.data.length; c++){
admin.firestore().collection("stats").doc(obj.stats.data[c].fixture_id.toString()).collection("all_stats").doc(obj.stats.data[c].team_id.toString()).set({
fixture_id : obj.stats.data[c].fixture_id,
team_id : obj.stats.data[c].team_id,
total_shots : obj.stats.data[c].shots && obj.stats.data[c].shots.total ? obj.stats.data[c].shots.total : null,
ongoal : obj.stats.data[c].shots && obj.stats.data[c].shots.ongoal ? obj.stats.data[c].shots.ongoal : null,
total_passes : obj.stats.data[c].passes && obj.stats.data[c].passes.total ? obj.stats.data[c].passes.total : null,
attacks : obj.stats.data[c].attacks && obj.stats.data[c].attacks.attacks ? obj.stats.data[c].attacks.attacks : null,
fouls : obj.stats.data[c].fouls,
corners : obj.stats.data[c].corners,
offsides : obj.stats.data[c].offsides,
possessiontime : obj.stats.data[c].possessiontime,
yellowcards : obj.stats.data[c].yellowcards,
redcards : obj.stats.data[c].redcards,
injuries : obj.stats.data[c].injuries,
saves : obj.stats.data[c].saves,
tackles : obj.stats.data[c].tackles
}).then(() => {
console.log("Stats table complete...");
})
}
})
return res.status(200).json(
console.log("successful")
)
})
.catch(err => {
console.log(err);
return res.status(500).json({
error: err
})
})
});

如果有任何帮助,我都将不胜感激。非常感谢。

您可能不应该同时启动所有这些firestore查询,而是等待每个查询完成后再启动下一个查询。

当您使onRequest回调函数async:时,这会更容易

exports.liveScores = functions.https.onRequest(async (req, res) => {
try {
let response = await axios.get(url);
var data = response.data.data;
for (let obj of data) {
await admin.firestore().collection("fixtures").doc(obj.id.toString()).set({
id: obj.id,
/* ... */ 
}); 
console.log("Fixtures table complete...");

for (let eventData of obj.events.data){
await admin.firestore().collection("events").doc(eventData.fixture_id.toString()).collection("all_events").doc(eventData.id.toString()).set({
type: eventData.type,
/* ... */
});
}
console.log("Events table complete...");

for (let lineupData of obj.lineup.data) {
await admin.firestore().collection("lineup").doc(lineupData.fixture_id.toString()).collection("lineup").doc(lineupData.player_id.toString()).set({
fixture_id: lineupData.fixture_id,
/* ... */
});
}
console.log("Lineup table complete...");
/* ... etc ... */
}
console.log("successful");
return res.status(200).json({ message: "successful" });
} catch(error) {
console.log(error);
return res.status(500).json({ error });
}
});

注意:不要将console.log("successful")作为参数传递给.json。您将希望传递一个对象作为参数。

相关内容

最新更新