HTTP-запрос POST внутри запланированной облачной функции не работает - PullRequest
0 голосов
/ 06 января 2020

Ниже мой планировщик, где я читаю данные из базы данных Firebase и обновляю данные, вызывая receiptValidationRequest(key, receiptData, date). Внутри этой функции я пытаюсь получить данные проверки из ответа HTTP-запроса на apple, но она не работает должным образом. Иногда это работает, и некоторые данные обновляются. Я не уверен, почему это происходит и чего мне там не хватает.

exports.updateDatabaseScheduler = functions.pubsub.schedule('0 0 */3 * *').onRun(async context => {
console.log('scheduler started');
await ref.on('value', function(snapshot) {
    snapshot.forEach(function(childSnapshot) {
      var childData = childSnapshot.val();
      console.log(i++ + " : " +childSnapshot.key);
      receiptValidationRequest(childSnapshot.key, childData['ReceiptData'], myDate);
    });
});
 console.log('scheduler finished');
});
async function receiptValidationRequest(userID, receiptData, myDate){
let password = 'my password';

try{
    const data = JSON.stringify({
        'receipt-data': receiptData,
        'password' : password,
        'exclude-old-transactions': false
    });

    const options = {
        resolveWithFullResponse: true,
        // hostname: 'sandbox.itunes.apple.com',
        hostname: 'buy.itunes.apple.com',
        port: 443,
        path: '/verifyReceipt',
        method: 'POST',
        json: true,
        headers: {
            'Content-Type': 'application/json',
            // 'Content-Length': data.length
        }
    };


    const req =  await https.request(options,res => {
        myStatusCode[0] = res.statusCode;
        let expireDate = [];
        let transactionId = [];
        var trialPeriod = [];
        var body = '';

        console.log(`statusCode: ${res.statusCode}`);
        res.on('data', d => {
            body = body + d;
            // console.log("body : "+body);
        });
        res.on("end", () => {
            body = JSON.parse(body);
            let array = Object.keys(body);

            console.log("body : "+body);
            //parsing data here
            insertIntoDB(userID, expireDate, transactionId, trialPeriod, myDate);

        });
    });
    req.write(data);
    req.end();
}catch(e){
    req.on('error', (error) => {
      console.error(error)
    });
 }   
}

Ответы [ 2 ]

1 голос
/ 06 января 2020

Вам необходимо вернуть обещание, которое разрешается после завершения всей асинхронной работы . Без этого облачные функции не знают, когда можно безопасно отключить функцию. То, что у вас есть сейчас, - это состояние гонки - иногда работа завершается до того, как Cloud Functions завершает свою работу, но не всегда.

Я предлагаю изучить другую HTTP-библиотеку, которая облегчает работу с обещаниями, такими как «запрос». -promise».

0 голосов
/ 06 января 2020

receiptValidationRequest - асинхронная c функция. Вы не ожидаете звонка forEach. Кроме того, используйте for..of или promise.all вместо forEach, поскольку forEach не работает с обещаниями в l oop.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...