我的Google Cloud Function从IBM Watson Text-to-Speech获取音频文件,将其保存到Firebase Storage,并获取签名的下载URL。有时,它将下载URL写入Firestore。大多数时候不会。这是代码:
exports.IBM_T2S = functions.firestore.document('Users/{userID}/Spanish/IBM_T2S_Request').onUpdate((change) => {
if (change.after.data().word != undefined) {
// get requested word
let word = change.after.data().word;
console.log(word);
let wordFileType = word + '.mp3';
var synthesizeParams = {
text: word,
accept: 'audio/mpeg',
voice: 'es-LA_SofiaVoice' // "es-ES_LauraVoice", "es-ES_EnriqueVoice", "es-US_SofiaVoice",
};
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
const bucket = storage.bucket('myApp.appspot.com');
const file = bucket.file('Audio/Spanish/Latin_America/' + wordFileType);
var TextToSpeechV1 = require('watson-developer-cloud/text-to-speech/v1');
var textToSpeech = new TextToSpeechV1({
username: 'groucho',
password: 'swordfish',
url: 'https://stream.watsonplatform.net/text-to-speech/api'
});
const options = { // construct the file to write
metadata: {
contentType: 'audio/mpeg',
metadata: {
source: 'IBM Watson Text-to-Speech',
languageCode: 'es-LA',
gender: 'Female'
}
}
};
var config = {
action: 'read',
expires: '03-17-2025'
};
return textToSpeech.synthesize(synthesizeParams).on('error', function(error) {
console.log(error);
}).pipe(file.createWriteStream(options))
.on('error', function(error) {
console.error(error);
})
.on('finish', function() {
console.log("Audio file written to Storage.");
// see https://stackoverflow.com/questions/42956250/get-download-url-from-file-uploaded-with-cloud-functions-for-firebase
file.getSignedUrl({
action: 'read',
expires: '03-17-2025'
})
.then(function(signedUrls) {
console.log(signedUrls[0]);
console.log("Word is now: " + word);
// Problem is here
return admin.firestore().collection('Dictionaries').doc('Spanish').collection('Words').doc(word).collection('Pronunciations').doc('Latin_America').update({
audioFile: signedUrls[0]
})
.then(function() {
console.log("Download URL written to database, IBM Latin American, update.");
return 0;
})
.catch(function(error) {
console.error(error);
return 0;
});
// *****
})
.catch(function(error) {
console.error(error);
return 0;
});
}); // close on
} else {
console.error("Error.");
return 0;
}
});
在this answer中道格·史蒂文森(Doug Stevenson)说
当所有异步工作完成时,您不会返回已解决的承诺 做完了。如果您不这样做,Cloud Functions会假设所有 您的工作已经完成,并且将减少所有资源,以及任何 待处理的工作将被关闭。
translate.translate()。then()。catch()返回的promise正在 忽略了。您对admin.firestore()... set()的嵌套调用具有类似的功能 问题。仅在每个对象上调用then()和catch()是不够的 承诺,因为then()和catch()都返回了另一个承诺。
我不知道返回的地点/地点。第一次异步调用
return textToSpeech.synthesize(synthesizeParams).on('error', function(error) {
必须返回以防止错误Function returned undefined, expected Promise or value
。也就是说,云端功能会在异步功能返回之前完成执行,因此您需要在第一个异步功能之前使用return
。
IBM Watson可能会返回回调,而不是诺言。
我返回了最后一个异步函数,正如道格·史蒂文森(Doug Stevenson)所说:
return admin.firestore().collection('Dictionaries').doc('Spanish').collection('Words').doc(word).collection('Pronunciations').doc('Latin_America').update({
audioFile: signedUrls[0]
})
.then(function() {
console.log("Download URL written to database, IBM Latin American, update.");
return 0;
})
.catch(function(error) {
console.error(error);
return 0;
});
换句话说,我返回第一个异步函数和最后一个异步函数。感觉不对。是否有文档说明退货在Google Cloud Functions中的位置?
我也将return 0;
放入了陷阱,以便即使出现错误也可以关闭云功能。
云功能通常在"Audio file written to Storage."
处停止,有时会继续记录下载URL,有时将下载URL写入Firestore。为什么有时将其写入Firestore而有时不写入?