Google Translate API和Firebase Firestore互相残杀

时间:2019-01-08 21:53:00

标签: firebase google-cloud-firestore google-cloud-functions google-translate

我们正在尝试编写一个Google Cloud Function,该函数从Google Translate API获取翻译,然后将结果写入Firebase Firestore数据库。每个都单独起作用,但是一起没有效果。换句话说,我们可以从Google翻译获得翻译。我们可以将数据写入Firestore。但是,如果我们尝试同时执行这两项操作,则不会从Google Translate那里获得翻译,并且不会将任何内容写入Firebase。我们没有收到错误消息。我们已经使用async await和Promise尝试了该代码。这是带有promise的代码:

    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 :(得分:2)

所有异步工作完成后,您不会返回已解决的承诺。如果您不这样做,Cloud Functions会假设您的所有工作都已完成,并且将占用所有资源,并且所有待处理的工作都将被关闭。

translate.translate().then().catch()返回的诺言被忽略。您对admin.firestore()...set()的嵌套调用也有类似的问题。仅对每个诺言都调用then()catch()是不够的,因为then()catch()都返回了另一个诺言。

在promise上,您也不必要混合使用try / catch和catch()。您不需要这两种策略来进行错误处理,只需一种或另一种即可。

在第二个示例中使用await时,您迫使JavaScript暂停,直到set()返回的promise表示的异步工作完成为止。这使您的函数仅在所有工作完成后才返回,这就是为什么它可以正常工作的原因。

观看我的video series在Cloud Functions中使用promise和async / await可能会对您有所帮助。正确处理诺言对于创建正确运行的功能至关重要。