Облачная функция Google не будет писать в Firebase Firestore - PullRequest
0 голосов
/ 10 февраля 2019

Моя облачная функция Google получает аудиофайл от 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;
  }
});

В этот ответ Дуг Стивенсон сказал

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

Обещание, возвращаемое translate.translate ().then (). catch () игнорируется.Ваш вложенный вызов 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 возвращает обратные вызовы, а не обещания.

Я возвращаю последнюю асинхронную функцию, как сказал Дуг Стивенсон:

  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, а иногда нет?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...