Google Translate API и Firebase Firestore убивают друг друга - PullRequest
0 голосов
/ 09 января 2019

Мы пытаемся написать облачную функцию Google, которая получает перевод от Google Translate API, а затем записать результаты в нашу базу данных Firebase Firestore. Каждый работает один, но вместе ничего не работает. Другими словами, мы можем получить перевод из Google Translate. Мы можем записать данные в Firestore. Но если мы попытаемся сделать то и другое, мы не получим перевод от Google Translate, и ничего не будет записано в Firebase. Мы не получаем сообщений об ошибках. Мы попробовали код с async await и с обещаниями. Вот код с обещаниями:

    exports.Google_EStranslateEN = functions.firestore.document('Users/{userID}/Spanish/Translation_Request').onUpdate((change, context) => {
      if (change.after.data().word != undefined) {
        const {Translate} = require('@google-cloud/translate');
        const projectId = 'myProject-cd99d';
        const translate = new Translate({
          projectId: projectId,
        });

        // The text to translate
        const text = change.after.data().word;
        // The target language
        const target = 'en';

        let translationArray = []; // clear translation array

        translate.translate(text, target)
        .then(results => {
          translation = results[0];
          translationArray.push(translation);

          try {
            // write translation to dictionary
admin.firestore().collection('Dictionaries').doc('Spanish').collection('Words').doc(text).collection('Translations').doc('English').set({
              'translationArray': translationArray,
              'language': 'en',
              'longLanguage': 'English'
            })
            .then(function() {
              console.log("Translation written");
            })
            .catch(function(error) {
              console.error(error);
            });
          } catch (error) {
            console.error(error);
          }
        })
        .catch(error => {
          console.error('ERROR:', error);
        });
      }
    });

Вот тот же код с async await:

exports.Google_EStranslateEN = functions.firestore.document('Users/{userID}/Spanish/Translation_Request').onUpdate((change, context) => { // triggers when browser writes a request word to the database
  if (change.after.data().word != undefined) {

async function getTranslation() {
  try {

    let translationArray = []; // clear translation array

    const {Translate} = require('@google-cloud/translate');
    const projectId = 'myProject-cd99d';

    const translate = new Translate({
      projectId: projectId,
    });

    // The text to translate
    const text = change.after.data().word;

    const options = {
      to: 'en',
      from: 'es',
      format: 'text'
    }

    let [translations] = await translate.translate(text, options);
    translations = Array.isArray(translations) ? translations : [translations]; // If translations is an array, leave it alone; if not, put it in an array
    translationArray.push(translations[0]);

    await admin.firestore().collection('Dictionaries').doc('Spanish').collection('Words').doc(text).collection('Translations').doc('English').set({
      'translationArray': translationArray,
      'language': 'en',
      'longLanguage': 'English'
    })
    .then(function() {
      console.log("Translation written");
    })
    .catch(function(error) {
      console.error(error);
    });
    // };
  } catch (error) {
    console.error(error);
  }
} // close getTranslation
getTranslation();   
}
});

1 Ответ

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

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

Обещание, возвращенное translate.translate().then().catch(), игнорируется. Ваш вложенный вызов admin.firestore()...set() имеет похожую проблему. Недостаточно просто звонить then() и catch() по каждому обещанию, потому что then() и catch() оба возвращают еще одно обещание.

Вы также излишне смешиваете использование try / catch с catch () в обещании. Вам не нужны обе стратегии для обработки ошибок, только одна или другая.

Когда вы использовали await во втором примере, вы заставляли JavaScript приостанавливаться до тех пор, пока асинхронная работа, представленная обещанием, возвращаемым set(), не будет завершена. Это позволило вашей функции возвращаться только после того, как вся работа была завершена, поэтому она работала правильно.

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

...