База данных Firebase Get All Value In Order Облачные функции

Я разрабатываю для 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

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

В цикле for получите databasearray[0], сделайте запрос, запишите файл, обработайте его с помощью Vision 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.info("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.info("DeviceToken: " + databaseArrayDeviceToken);

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

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

            var databaseArraysecondval = databaseArray[i][3];
            console.info("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.info("file written");
                    })

            }

        });

        return true;
    });

Если бы это был я, я бы переключился на TypeScript и использовал Async/Await. Эти .then() действительно плохие

Mocas 22.01.2019 17:31

Пожалуйста, объясните свой ответ. Как я могу написать TypeScript? Я чисто новичок :)

user3352895 22.01.2019 17:47

следите за этой серией, очень полезно youtube.com/…

Mocas 22.01.2019 21:54

Я смотрю видео с вашим предложением. Но я не понял. Так жаль :(

user3352895 22.01.2019 23:32

Только что обнаружил, что js поддерживает async/await. пожалуйста, прочтите это blog.risingstack.com/mastering-async-await-in-nodejs

Mocas 23.01.2019 09:28

Сравните раздел «Решение 1: рождественская елка .then» с разделом «Благодаря использованию async/await наши проблемы волшебным образом исчезли».

Mocas 23.01.2019 09:43

Вау! Я получил решение с вашей помощью. Я публикую свое решение в разделе ответов. Но сейчас у меня другие проблемы. Цикл for ждет ответа с помощью await, но иногда он зависает на одном шаге. А иногда для функции цикла вызывается более одной. Я этого не понимаю. Я пишу их в разделе ответов. Еще раз спасибо.

user3352895 24.01.2019 13:42

Нет проблем, не стесняйтесь отметить мой комментарий как полезный, щелкнув треугольник вверх. Опубликуйте еще один вопрос с вашей проблемой

Mocas 24.01.2019 13:48

Я обновил свой ответ кодом. Взгляни, пожалуйста. Спасибо.

user3352895 24.01.2019 17:02
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
9
386
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я нашел решение с помощью Mocas. Вот решение. Я использую функции async/await в коде. Теперь цикл for ожидает ответа функции. Но сейчас у меня другие проблемы. Я думаю, что основная асинхронная функция зависает из-за ожидания. И затем следующий почасовой триггер снова запускается. Таким образом, журнал консоли показывает 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.info("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.info(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.info("Database Arrays " + i + ". elements: ");


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

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

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

            var databaseArraysecond = databaseArray[i][3];
            console.info("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.info("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;
    };

Другие вопросы по теме