Firebase admin SDK не работает в облачном планировщике (PubSub) - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть приложение, и я хочу обновлять информацию о погоде каждые 5 минут. Я создаю функцию PubSub на облачной функции Google, чтобы получать сведения о погоде с веб-сайта weatherstack.com , а затем пытаюсь сохранить результат в FireStore с помощью Admin SDK . 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;
};

пакет. 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
}

1 Ответ

1 голос
/ 19 февраля 2020

Вы должны вернуть обещание, которое разрешается после завершения всей асинхронной работы в вашей облачной функции (т. Е. Вызов метода weatherstack API и Firestore update()).

Это объясняется в официальной серии видеороликов Firebase здесь . В частности, посмотрите три видеофильма под названием «Учитесь JavaScript Обещания» (части 2 и 3 посвящены, в первую очередь, функциям облачных функций, запускаемым на заднем плане, но прежде стоит посмотреть часть 1).


request используемая вами библиотека изначально поддерживает интерфейсы обратного вызова , но не возвращает обещание .

. Вы можете использовать библиотеку request-promise и метод rp(), который "возвращает" обычное обещание Promise / 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) => {...}) правильно , Похоже, что это не так, см. do c для получения более подробной информации.

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