这是我的问题的后续https://stackoverflow.com/questions/54100270/google-translate-api-and-firebase-firestore-are-killing-each-other
。道格·史蒂文森说我需要恢复我的职能。我们看了他的视频Learn JavaScript Promises (Pt. 3) for sequential and parallel work in Cloud Functions
几百次...
我正在使用两个函数。第一个是调用 Google Translate,现在返回翻译。第二个功能是 Firestoreset()
调用,将翻译写入数据库。这set()
如果我不执行 Google Translate 调用,则可以工作,但它们一起崩溃。具体来说,如果我打电话Firebase set()
比谷歌翻译功能执行,我们看到Result1
,仅此而已。换句话说,调用数据库会停止代码将翻译推入数据库translationArray
.
现在这是我的代码:
exports.Google_EStranslateEN = functions.firestore.document('Users/{userID}/Spanish/Translation_Request_NOT').onUpdate((change, context) => {
if (change.after.data().word != undefined) {
const { Translate } = require('@google-cloud/translate');
// Your Google Cloud Platform project ID
const projectId = 'myProject-cd99d';
// Instantiates a client
const translate = new Translate({
projectId: projectId,
});
// The text to translate
const text = change.after.data().word;
console.log(text);
// The target language
const target = 'en';
let translationArray = []; // clear translation array
const finalPromise = translate.translate(text, target)
.then(function (results) {
console.log("Result1: " + results);
console.log(Array.isArray(results));
console.log(results[0]);
let translation = results[0];
console.log(translation);
return translation
})
.then(function (results) {
console.log("Translation: " + results);
translationArray.push(results);
return translationArray
})
.then(function (results) {
console.log("TranslationArray: " + translationArray);
console.log("Result2: " + results);
console.log("Text: " + text)
return admin.firestore().collection('Dictionaries').doc('Spanish').collection('Words').doc(text).collection('Translations').doc('English').set({
translationArray: results,
language: 'en',
longLanguage: 'English'
});
})
.then(function (results) {
console.log("Result3: " + results)
console.log("Write succeeded!");
})
.catch(function (error) {
console.error(error);
});
} // close if
return 0;
}); // close oxfordPronunciationUS
消防店set()
调用不会返回任何内容,并且会终止 Google Translation 调用。具体来说,如果没有 Firestore 调用,代码会一直执行并记录所有内容。通过 Firestore 调用,两个函数都不会执行(Google Translate 永远不会被调用),并且“文本”之后不会记录任何内容。
我不明白什么const finalPromise
做。它看起来像是一个未使用的常量。
We read 为什么 Firebase API 是异步的? https://medium.com/google-developers/why-are-firebase-apis-asynchronous-callbacks-promises-tasks-e037a6654a93并尝试了这段代码:
var promise = admin.firestore().collection('Dictionaries').doc('Spanish').collection('Words').doc(text).collection('Translations').doc('English').set({
translationArray: translationArray,
language: 'en',
longLanguage: 'English'
});
promise.then(...)
那没有帮助。
我尝试切换到 IBM Watson Translate,但也发生了同样的事情。如果没有数据库调用,翻译功能就可以完美运行。通过 Firestore 调用,它会获取翻译,运行forEach
,然后当我尝试将单词推入数组时停止。translationsArray
不记录并且没有任何内容写入数据库。
exports.IBM_EStranslateEN = functions.firestore.document('Users/{userID}/Spanish/Translation_Request_IBM').onUpdate((change, context) => {
if (change.after.data().word != undefined) {
let word = change.after.data().word;
let wordArray = [];
wordArray.push(word);
var LanguageTranslatorV3 = require('watson-developer-cloud/language-translator/v3');
var languageTranslator = new LanguageTranslatorV3({
version: '2018-05-01',
iam_apikey: 'swordfish',
url: 'https://gateway.watsonplatform.net/language-translator/api',
headers: {
'Content-Type': 'application/json'
}
});
var parameters = {
"text": wordArray,
"model_id": "es-en",
"source": "es",
"target": "en"
};
let translationsArray = [];
languageTranslator.translate(
parameters,
function (err, response) {
if (err) {
console.log('error:', err);
} else {
response.translations.forEach(function (translation) {
console.log(translation.translation);
translationsArray.push(translation.translation);
});
console.log(translationsArray);
admin.firestore().collection('Dictionaries').doc('Spanish').collection('Words').doc(word).collection('Translations').doc('English').set({
translationsArray: translationsArray,
language: 'en',
longLanguage: 'English'
})
.then(function () {
console.log("Translations written to database.");
})
.catch(function (error) {
console.error(error);
});
}
}
);
}
return 0;
});
我还编写了相同的云函数,调用牛津英语词典进行翻译。这非常有效,将翻译写入数据库:
exports.Oxford_EStranslateEN = functions.firestore.document('Users/{userID}/Spanish/Translation_Request').onUpdate((change, context) => {
if (change.after.data().word != undefined) {
let word = change.after.data().word;
let options = {
uri: 'https://od-api.oxforddictionaries.com/api/v1/entries/es/' + change.after.data().word + '/translations%3Den', // translations=es
headers: {
"Accept": "application/json",
'app_id': 'groucho',
'app_key': 'swordfish'
},
json: true
};
let translationsArray = [];
return rp(options)
.then(function (wordObject) {
wordObject.results.forEach(function (result) {
result.lexicalEntries.forEach(function (lexicalEntry) {
lexicalEntry.entries.forEach(function (entry) {
entry.senses.forEach(function (sense) {
if (sense.translations) {
sense.translations.forEach(function (translation) {
translationsArray.push(translation.text);
});
} // close if
else {
if (sense.subsenses) {
sense.subsenses.forEach(function (subsense) {
if (subsense.translations) {
subsense.translations.forEach(function (translation) {
translationsArray.push(translation.text);
}); // close forEach
} // close if
else {
// console.log("No Translation");
} // close else
}); // close forEach
} // close if
} // close else
}); // close forEach
}); // close forEach
}); // close forEach
}); // close forEach
translationsArray = [...new Set(translationsArray)]; // removes duplicates
return admin.firestore().collection('Dictionaries').doc('Spanish').collection('Words').doc(word).collection('Translations').doc('English').set({
translationsArray: translationsArray,
source: 'OED',
dateAdded: Date.now(), // timestamp
longLanguage: 'English',
shortLanguage: 'en',
word: word
})
.then(function () {
// console.log("Document written.");
})
.catch(function (error) {
console.log("Error writing document: ", error);
})
})
.then(function () {
// console.log("Document written for Oxford_EStranslateEN.");
})
.catch(function (error) {
console.log("error: " + error);
});
} // close if
// return 0;
});
一个区别是我通过 HTTP 请求调用 OED,使用rp
(请求-承诺)。我打电话return rp(options)
。这显然返回了一个承诺,并且该承诺被显式地返回。问题似乎是,在 Google 版本中,当我调用 Google Translate 时,我没有返回承诺,而 IBM Watson 返回的是回调,而不是承诺,而且我没有返回该承诺。