База данных Firebase Получить все значения в порядке облачных функций - PullRequest
0 голосов
/ 22 января 2019

Я разрабатываю для Firebase Cloud Functions. У меня есть база данных Firebase Realtime, как это:

----- myData 
      -------eqewrwrepere (this one is a device token)
                         ---------Lta+sde-fer (this one is a firebase id)
                                  firstvalue  : "a"
                                  secondvalue : "b"

                        ----------Qrgd+ad-qdda (this one is second firebase id)
                                  firstvalue  : "c"
                                  secondvalue : "d"

      -------eqwerSAsdqe (this one is another device token)
                        ---------Lta+sde-fer (this one is a firebase id)
                                 firstvalue  : "x"
                                 secondvalue : "y"

                       ----------Qrgd+ad-qdda (this one is second firebase id)
                                 firstvalue  : "z"
                                 secondvalue : "t"

Я получаю эти данные по этому коду. С помощью этого кода я получаю все данные и помещаю их в массив. И когда выборка завершена, я зацикливаю этот массив для поиска элементов. Я разработчик iOS, поэтому я новичок в NodeJS. Вот что я хочу сделать:

  1. Получить firstvalue для каждой базы данных.
  2. Сделайте запрос API с первым значением для каждой базы данных.
  3. Api возвращает изображение.
  4. Запись временного каталога изображения.
  5. Обработать это изображение для visionApi.
  6. Извлечь текст.
  7. Обновление базы данных.
  8. Отправить уведомление для deviceToken

Теперь я могу получить элементы базы данных в моем массиве. Когда я делаю запрос в цикле, запрос называется async. Так что цикл for продолжается, но ответный запрос или запись файла и обработка видения выполняются только один раз.

В цикле for получите databasearray [0], создайте запрос, напишите файл, обработайте его с помощью API api, обновите базу данных и перейдите к следующему элементу databasearray [1].

Я читал о Promises на разных страницах. Но я не поняла.

Спасибо.

'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var request = require('request');
var fs = require('fs');
//var fs = require("fs");
// Get a reference to the Cloud Vision API component
const Vision = require('@google-cloud/vision');
const vision = new Vision.ImageAnnotatorClient();
// Imports the Google Cloud client library
//const {Storage} = require('@google-cloud/storage');
var fs = require("fs");
var os = require("os");
var databaseArray = [];


exports.hourly_job = functions.pubsub
.topic('hourly-job')
.onPublish((event) => {
    console.log("Hourly Job");


    var db = admin.database();
    var ref = db.ref("myData")


    ref.once("value").then(function(allData) {

        allData.forEach(function(deviceToken) {

            deviceToken.forEach(function(firebaseIDs) {

                var deviceTokenVar = deviceToken.key;
                var firebaseIDVar = firebaseIDs.key;
                var firstvalue = firebaseIDs.child("firstvalue").val();
                var secondvalue = firebaseIDs.child("secondvalue").val();


                var items = [deviceTokenVar, firebaseIDVar, firstvalue, secondvalue];

                databaseArray.push([...items]);


            });

        });
        return databaseArray;
    }).then(function(databasem) {

        var i;
        for (i = 0; i < databaseArray.length; i++) {

            var databaseArrayDeviceToken = databaseArray[i][0];
            console.log("DeviceToken: " + databaseArrayDeviceToken);

            var databaseArrayFirebaseID = databaseArray[i][1];
            console.log("FirebaseID: " + databaseArrayFirebaseID);

            var databaseArrayfirstvalue = databaseArray[i][2];
            console.log("firstval: " + databaseArrayfirstvalue);

            var databaseArraysecondval = databaseArray[i][3];
            console.log("Second: " + databaseArraysecondval);


            var url = "http://api.blabla" + databaseArrayfirstvalue;

            /////////////here make a request, pause loop, process returned image, but how //////////////////////         
            request.get({
                    url: url,
                    encoding: 'binary'
                }, function(error, httpResponse, body) {


                    if (!error && httpResponse.statusCode == 200) {

                        fs.writeFileSync('/tmp/processed.jpg', body, 'binary')
                        console.log("file written");
                    })

            }

        });

        return true;
    });

1 Ответ

0 голосов
/ 24 января 2019

Я нашел решение с помощью Mocas. Вот решение. Я использую функции async / await в коде. Теперь цикл ожидает ответа функции. Но сейчас у меня другие проблемы. Я думаю, что основная асинхронная функция зависает из-за ожидания. И затем следующий почасовой триггер, он снова запускается. Таким образом, консольный журнал показывает 15-16-17 или более значений «i» в цикле for. У меня есть 4 элемента в массиве базы данных, но журнал консоли показывает больше, чем это каждый час. И это увеличивается с каждым разом. Так что я думаю, что я должен отменить эту функцию ожидания после тайм-аута. Но я не знаю как. Вот код:

    use strict';

    const functions = require('firebase-functions');
    const admin = require('firebase-admin');
    admin.initializeApp(functions.config().firebase);
    var request = require('request-promise').defaults({ encoding: null });
    var fs = require('fs');
    // Get a reference to the Cloud Vision API component
    const Vision = require('@google-cloud/vision');
    const vision = new Vision.ImageAnnotatorClient();
    var os = require("os");
    var databaseArray = [];
    var uniqueFilename = require('unique-filename')

    exports.hourly_job = functions.pubsub
      .topic('hourly-job')
      .onPublish((event) => {
        console.log("Hourly Job");




        var db = admin.database();
        var ref = db.ref("myData")


       ref.once("value").then(function(allData) {

       allData.forEach(function(deviceToken) {

              deviceToken.forEach(function(firebaseIDs) {

            var deviceTokenVar = deviceToken.key;
            var firebaseIDVar = firebaseIDs.key;
            var firstvalue = firebaseIDs.child("firstvalue").val();
            var secondvalue = firebaseIDs.child("secondvalue").val();


            var items = [deviceTokenVar, firebaseIDVar, firstvalue, secondvalue];

            databaseArray.push([...items]);
            //console.log(databaseArray);   
    //return true;
    });   
    //return true;
    });
    return databaseArray;
    }).then(function (databasem) {

        main().catch(console.error);                
            });

    return true;
    });

    const main = async () => {

        var i;
        for (i = 0; i < databaseArray.length; i++) {

            console.log("Database Arrays " + i + ". elements: ");


            var databaseArrayDeviceToken = databaseArray[i][0];
            console.log("DeviceToken: " + databaseArrayDeviceToken);

            var databaseArrayFirebaseID = databaseArray[i][1];
            console.log("FirebaseID: " + databaseArrayFirebaseID);

            var databaseArrayfirst = databaseArray[i][2];
            console.log("first: " + databaseArrayfirst);

            var databaseArraysecond = databaseArray[i][3];
            console.log("second: " + databaseArraysecond);



             if (databaseArrayfirst != "") {

            var apiUrl = "http://api.blabla;

            try {
            const apiBody = await request.get(apiUrl); 


        ///////////////////////////vison start//////////////////////    

            const visionResponseBody = await vision.documentTextDetection(apiBody)

             var visionResponse = visionResponseBody[0].textAnnotations[0].description;

             console.log("Vision response text " + visionResponse );

             ...some logic here about response...

    /////////////////////////////////////////////////   
             var getdatabasevar = await admin.database().ref("myData/" + databaseArrayDeviceToken + "/" + databaseArrayFirebaseID);

             await getdatabasevar.update({
             "firstvalue": visionResponse
             });  


    /////////////////////////////////////////////////  

             var getanotgerdatabasevar = await admin.database().ref("myData/" + databaseArrayDeviceToken + "/" + databaseArrayFirebaseID + "/" + "secondvalue");

             await getanotgerdatabasevar.once("value")
              .then(function(var) {

              ..some logic..


              //send notification


              });
    } catch (error) {
            console.error(error);
            }
    ///////////////////////////vison end//////////////////////  


        }

    };
    return true;
    };
...