我有一个应用程序,我希望每5分钟更新天气细节。我在谷歌云功能上构建了一个PubSub函数,以从weatherstack.com网站获取天气细节,然后我尝试使用管理SDK将结果保存在FireStore上。天气API工作得很好,但是没有触发将数据写入FireStore的函数。
我的代码:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const requestApi = require('request');
admin.initializeApp();
exports.WeatherPubSub = (event, context) => {
requestApi({
url: 'http://api.weatherstack.com/current?access_key=XXXXXXXXXXXXXXXXXXXX&query=XXXXX',
method: "POST"
}, (error, response, body) => {
//console.log(JSON.parse(body));
if (error) {
console.log('error:', error); // Print the error if one occurred
} else {
console.log("=> "+ response.statusCode);
//Call firestore to update weather data
return admin.firestore().collection('settings').doc('weather').update({
temperature: body.current['temperature'],
humidity: body.current['humidity'],
weather_descriptions: body.current['weather_descriptions'][0]
}).then(function() {
console.log('Done!');
});
}
});
//return null;
};
package.json
{
"name": "functions",
"version": "0.0.2",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"dependencies": {
"@google-cloud/pubsub": "^1.5.0",
"firebase-admin": "^8.9.2",
"firebase-functions": "^3.3.0",
"request": "^2.88.2"
},
"devDependencies": {
"firebase-functions-test": "^0.1.6"
},
"private": true
}
发布于 2020-02-19 03:28:04
您必须返回一个承诺,当云函数中的所有异步工作完成(即调用weatherstack
API和Firestore update()
方法)时解决该问题。
这在官方的Firebase视频系列这里中得到了解释。特别是观看题为“学习JavaScript承诺”的三个视频(第2和第3部分特别关注背景触发的云函数,但在第1部分之前确实值得一看)。
您使用的request
库支持回调接口(原生),但不返回承诺的。
您可以使用request-promise
库和rp()
方法“返回常规承诺/A+兼容承诺”,然后按照以下方式调整代码:
//.....
var options = {
method: 'POST',
uri: 'http://api.weatherstack.com/current?access_key=XXXXXXXXXXXXXXXXXXXX&query=XXXXX'
};
return rp(options)
.then(body => {
return admin.firestore().collection('settings').doc('weather').update({
temperature: body.current['temperature'],
humidity: body.current['humidity'],
weather_descriptions: body.current['weather_descriptions'][0]
}
})
.catch(err => {
console.log(err);
return null;
});
//.....
此外,您应该反复检查声明云函数(exports.WeatherPubSub = (event, context) => {...}
)的方式是否正确。情况似乎并非如此,有关更多细节,请参见文档。
https://stackoverflow.com/questions/60298998
复制