我正在尝试发出SOAP请求,并将结果推送到Firebase数据库。
我编写了一个函数,当使用节点index.js进行控制台调用时,该函数可以正常工作。记录我的SOAP请求的结果。
我有一个在HTTPS请求上触发的firebase函数。该函数调用我的,但是没有数据被推送到数据库。
function getStopData(){
(async () => {
const { response } = await soapRequest(url, headers, xml); // Optional timeout parameter(milliseconds)
const { body, statusCode } = response;
parseString(body, function (err, result) {
var envelope = result['soap:Envelope'];
var body = envelope['soap:Body'];
var result = body.pop();
var resultXml = result.GetRealTimeStopDataResponse.pop().GetRealTimeStopDataResult.pop()
var stopData = resultXml['diffgr:diffgram'].pop().DocumentElement.pop().StopData;
var busses = []
for (bus in stopData) {
delete stopData[bus].$
busses.push(stopData[bus]);
}
admin.database().ref('/test14').push({testText: 'test14Text'});
});
})();
}
admin.initializeApp();
exports.test14 = functions.region('europe-west1')
.https.onRequest(async (req, res) => {
getStopData(); //Runs function, but no test is pushed to DB
admin.database().ref('/test14').push({testText: 'test14Text'}); //This is pushed to dB
return res.send("Success");
});
测试字符串被火力函数推入。常规函数中的测试字符串不是。
谢谢。
如果firebase不适合此应用程序,请提出其他建议。我试图创建一个每2分钟运行一次的函数来发出SOAP请求并存储结果。
编辑:根据第一个答案,我已经修改了我的代码以匹配建议的代码。这给我带来了另一个错误。
5:25:49.623 PM
test14
SOAP FAIL: Error: timeout of 10000ms exceeded
5:25:49.624 PM
test14
Unhandled rejection
5:25:49.624 PM
test14
Error: timeout of 10000ms exceeded at createError (/srv/node_modules/axios-https-proxy-fix/lib/core/createError.js:16:15) at Timeout.handleRequestTimeout [as _onTimeout] (/srv/node_modules/axios-https-proxy-fix/lib/adapters/http.js:216:16) at ontimeout (timers.js:498:11) at tryOnTimeout (timers.js:323:5) at Timer.listOnTimeout (timers.js:290:5)
5:25:49.631 PM
test14
Function execution took 10712 ms, finished with status: 'crash'
我不确定为什么会出现SOAP Fail,因为与节点index.js一起运行仍会产生正确的数据记录到控制台。
MonitoredVehicleJourney_Monitored: [ 'true' ],
MonitoredVehicleJourney_InCongestion: [ 'false' ],
MonitoredVehicleJourney_BlockRef: [ '37006' ],
MonitoredVehicleJourney_VehicleRef: [ '44138' ],
MonitoredCall_VisitNumber: [ '4' ],
MonitoredCall_VehicleAtStop: [ 'false' ],
MonitoredCall_AimedArrivalTime: [ '2019-04-14T18:19:45+01:00' ],
MonitoredCall_ExpectedArrivalTime: [ '2019-04-14T18:19:45+01:00' ],
MonitoredCall_AimedDepartureTime: [ '2019-04-14T18:19:45+01:00' ],
MonitoredCall_ExpectedDepartureTime: [ '2019-04-14T18:19:45+01:00' ],
Timestamp: [ '2019-04-14T17:34:14.97+01:00' ],
LineNote: [ '' ] } ]
答案 0 :(得分:0)
在Cloud Functions上运行代码时,需要支付运行时间。因此,在您将响应发送回调用客户端之后,使用return res.send("Success")
,Cloud Functions运行时将立即终止容器。
但是您的SOAP调用是异步发生的,并且在res.send
运行之后继续。在这种情况下,您必须告诉Cloud Functions完成时间。由于您不这样做,因此Cloud Functions可以随时终止运行代码的容器,显然在这种情况下,这是在SOAP请求完成之前发生的。
解决方案是仅在SOAP调用的结果返回时才编写响应:
function getStopData(){
(async () => {
const { response } = await soapRequest(url, headers, xml); // Optional timeout parameter(milliseconds)
const { body, statusCode } = response;
parseString(body, function (err, result) {
var envelope = result['soap:Envelope'];
var body = envelope['soap:Body'];
var result = body.pop();
var resultXml = result.GetRealTimeStopDataResponse.pop().GetRealTimeStopDataResult.pop()
var stopData = resultXml['diffgr:diffgram'].pop().DocumentElement.pop().StopData;
var busses = []
for (bus in stopData) {
delete stopData[bus].$
busses.push(stopData[bus]);
}
admin.database().ref('/test14').push({testText: 'test14Text'}).then(() => {
res.send("Success");
});
});
})();
}
admin.initializeApp();
exports.test14 = functions.region('europe-west1')
.https.onRequest(async (req, res) => {
getStopData(res);
});