Как я могу отправить результат внешнего запроса в realtimeDB в firebase? - PullRequest
0 голосов
/ 14 апреля 2019

Я пытаюсь сделать запрос SOAP и отправить результаты в базу данных Firebase.

Я написал функцию, которая работает правильно при вызове с использованием узла index.js для console.log результатовмой запрос SOAP.

У меня есть функция firebase, которая запускается по запросу HTTPS.Эта функция вызывает мой, но никакие данные не отправляются в базу данных.

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, которая перемещается.Тестовая строка в обычной функции не является.

Заранее спасибо.

Если база данных 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, так как при работе с узлом 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: [ '' ] } ]

1 Ответ

0 голосов
/ 14 апреля 2019

Когда вы запускаете код в облачных функциях, вы платите за количество времени, которое он выполняет. По этой причине среда выполнения Cloud Functions завершит работу контейнера сразу после того, как вы отправите ответ вызывающему клиенту, что вы делаете с return res.send("Success").

Но ваш SOAP-вызов происходит асинхронно и продолжается после этого res.send. В этом сценарии вам нужно будет сообщить 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);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...