Cloud Functions 在模拟器中工作但在部署时不工作
Cloud Functions working in emulator but not when deployed
我正在尝试在 Firebase 中创建文档后创建一个集合和一个文档。
它在模拟器中运行良好,但是当我将我的函数部署到 Firebase 项目时,它们不会创建该集合和文档。
但如果我在现有文档(快照)中创建字段,它就可以工作。
在函数中,我从 API 获取数据并将其写入新文档(目前未创建)。
函数:
exports.quoteEndPoint = functions.firestore.document('users/{userID}/followedStocks/{stockID}')
.onCreate((snap, context) => {
const stock_id = context.params.stockID;
const user_id = context.params.userID;
var request = require('request');
var http = require('https');
const options = {
"method": "GET",
"hostname": "alpha-vantage.p.rapidapi.com",
"port": null,
"path": '/query?function=GLOBAL_QUOTE&symbol='+stock_id+'&datatype=json',
"headers": {
"x-rapidapi-host": "%API_HOST%",
"x-rapidapi-key": "%API_KEY%",
"useQueryString": true
}
};
const req = http.request(options, function(res){
const chunks = [];
res.on('data', function(chunk){
chunks.push(chunk);
});
res.on('end', function(){
const body = Buffer.concat(chunks);
//console.log(body.toString());
const result = JSON.parse(body.toString());
console.log(result);
//set values from json responso to Firebase
return snap.ref.collection('quoteEndPoint').doc('data').set(
{
'symbol': result['Global Quote']['01. symbol'],
'open': result['Global Quote']['02. open'],
}, { merge: true }).then(()=>{
console.log('New quoteEndPoint fields for ' + stock_id + ' added to Firebase');
})
.catch(err => {
console.log(err);
});
});
})
.on('error',(err) => {
console.log('Error: '+err.message);
});
req.end();
return true;
});
我尝试使函数:function() 异步,但没有成功。
在模拟器中正在创建值并将其填充到正确的路径:/users/7nDGdHmZDuoDiJkxixgz/followedStocks/AMD/quoteEndPoint/data
有人可以帮忙吗?
谢谢
您的问题很可能是因为使用 request
的调用没有 return 承诺,而在 Cloud Functions 中由后台事件触发(例如 .onCreate()
用于 Firestore)你必须 return 一个承诺。观看此 official video series 了解更多详情:特别是标题为“学习 JavaScript Promises”的 3 个视频。
此外,request
已弃用。
可以使用axios, which returns a Promise, or node-fetch. You need to chain the promises returned的异步操作,即axios和Firestore的异步调用,如下代码“骨架”所示:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const axios = require('axios');
exports.quoteEndPoint = functions.firestore.document('users/{userID}/followedStocks/{stockID}')
.onCreate((snap, context) => {
const stock_id = context.params.stockID;
const user_id = context.params.userID;
return axios({
method: 'get',
url: 'http://....'
// ... See the doc
})
.then(response => {
// ...
return snap.ref.collection('quoteEndPoint').doc('data').set(...);
});
});
我正在尝试在 Firebase 中创建文档后创建一个集合和一个文档。
它在模拟器中运行良好,但是当我将我的函数部署到 Firebase 项目时,它们不会创建该集合和文档。
但如果我在现有文档(快照)中创建字段,它就可以工作。
在函数中,我从 API 获取数据并将其写入新文档(目前未创建)。
函数:
exports.quoteEndPoint = functions.firestore.document('users/{userID}/followedStocks/{stockID}')
.onCreate((snap, context) => {
const stock_id = context.params.stockID;
const user_id = context.params.userID;
var request = require('request');
var http = require('https');
const options = {
"method": "GET",
"hostname": "alpha-vantage.p.rapidapi.com",
"port": null,
"path": '/query?function=GLOBAL_QUOTE&symbol='+stock_id+'&datatype=json',
"headers": {
"x-rapidapi-host": "%API_HOST%",
"x-rapidapi-key": "%API_KEY%",
"useQueryString": true
}
};
const req = http.request(options, function(res){
const chunks = [];
res.on('data', function(chunk){
chunks.push(chunk);
});
res.on('end', function(){
const body = Buffer.concat(chunks);
//console.log(body.toString());
const result = JSON.parse(body.toString());
console.log(result);
//set values from json responso to Firebase
return snap.ref.collection('quoteEndPoint').doc('data').set(
{
'symbol': result['Global Quote']['01. symbol'],
'open': result['Global Quote']['02. open'],
}, { merge: true }).then(()=>{
console.log('New quoteEndPoint fields for ' + stock_id + ' added to Firebase');
})
.catch(err => {
console.log(err);
});
});
})
.on('error',(err) => {
console.log('Error: '+err.message);
});
req.end();
return true;
});
我尝试使函数:function() 异步,但没有成功。
在模拟器中正在创建值并将其填充到正确的路径:/users/7nDGdHmZDuoDiJkxixgz/followedStocks/AMD/quoteEndPoint/data
有人可以帮忙吗?
谢谢
您的问题很可能是因为使用 request
的调用没有 return 承诺,而在 Cloud Functions 中由后台事件触发(例如 .onCreate()
用于 Firestore)你必须 return 一个承诺。观看此 official video series 了解更多详情:特别是标题为“学习 JavaScript Promises”的 3 个视频。
此外,request
已弃用。
可以使用axios, which returns a Promise, or node-fetch. You need to chain the promises returned的异步操作,即axios和Firestore的异步调用,如下代码“骨架”所示:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const axios = require('axios');
exports.quoteEndPoint = functions.firestore.document('users/{userID}/followedStocks/{stockID}')
.onCreate((snap, context) => {
const stock_id = context.params.stockID;
const user_id = context.params.userID;
return axios({
method: 'get',
url: 'http://....'
// ... See the doc
})
.then(response => {
// ...
return snap.ref.collection('quoteEndPoint').doc('data').set(...);
});
});