在Firebase Cloud Functions中包含异步功能(附加错误“解析错误:意外的令牌功能”)

时间:2018-12-12 01:59:03

标签: javascript node.js firebase google-cloud-functions firebase-cli

问题

如何将async辅助方法添加到 Cloud Functions' index.js 文件中?如将此Stack fs.writeFile in a promise, asynchronous-synchronous stuff中所述,将async转换为 Promise 时,需要使用await函数才能使用fs.writefile。但是, lint 不赞成在exports函数之外向 index.js 文件添加其他方法。

错误

84 行是指辅助功能async function writeFile

  

用户/adamhurwitz/coinverse/coinverse-cloud-functions/functions/index.js     84:7错误解析错误:意外的令牌功能

     

✖1个问题(1个错误,0个警告)

     

npm错误!代码ELIFECYCLE

     

npm错误! errno 1

     

npm错误!功能@皮棉:eslint .

     

npm错误!退出状态1

     

npm错误!

     

npm错误!在functions @ lint脚本上失败。

     

npm错误! npm可能不是问题。上面可能还有其他日志记录输出。

     

npm错误!可以在以下位置找到此运行的完整日志:

     

npm错误! /Users/adamhurwitz/.npm/_logs/2018-12-12T01_47_50_684Z-debug.log

     

错误:函数预部署错误:命令以非零退出代码1终止

设置

index.js

const path = require('path');
const os = require('os');
const fs = require('fs');
const fsPromises = require('fs').promises;
const util = require('util');
const admin = require('firebase-admin');
const functions = require('firebase-functions');
const {Storage} = require('@google-cloud/storage');
const textToSpeech = require('@google-cloud/text-to-speech');

const storage = new Storage({
  projectId: 'project-id',
});
const client = new textToSpeech.TextToSpeechClient();

admin.initializeApp();

exports.getAudiocast = functions.https.onCall((data, context) => {
  const bucket = storage.bucket('gs://[bucket-name].appspot.com');
  var fileName;
  var tempFile;
  var filePath;

  return client.synthesizeSpeech({
    input: {text: data.text },
    voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
    audioConfig: {audioEncoding: 'MP3'},
  })
  .then(responses => {
    var response = responses[0]; 
    fileName = data.id + '.mp3'
    tempFile = path.join(os.tmpdir(), fileName);  
    return writeFile(tempFile, response.audioContent)
  })
  .catch(err => {
    console.error("Synthesize Speech Error: " + err);
  })
  .then(() => {
     filePath = "filePath/" + fileName;
     return bucket.upload(tempFile, { destination: filePath })
  })
  .catch(err => {
     console.error("Write Temporary Audio File Error: " + err);
  })
  .then(() => {
   return { filePath: filePath }
  })
  .catch(err => {
     console.error('Upload Audio to GCS ERROR: ' + err);
  });
});

Helper方法:

async function writeFile(tempFile, audioContent) {
    await fs.writeFile(tempFile, audioContent, 'binary');
}

尝试的解决方案

按照帖子Cloud Functions for Firebase Async Await style中的建议启用Node.js 8

  1. Set Node.js version "engines": {"node": "8"}

  2. return await fs.writeFile(tempFile, audioContent, 'binary');

棉绒不喜欢这种解决方案。

6 个答案:

答案 0 :(得分:49)

我尝试了以上所有对我不起作用的解决方案。这是由于我的 package.json 中的语法错误:

"scripts": {
    "lint": "eslint ."
  },

改为:

"scripts": {
    "lint": "eslint"
  },

就像 Burak 在评论中所说的,这个点在我们创建 firebase 函数时默认放置

答案 1 :(得分:8)

您的eslint未配置为了解ECMAScript 2017语法。 Fireabse CLI默认创建的.eslint.json配置文件包括以下配置:

"parserOptions": {
  // Required for certain syntax usages
  "ecmaVersion": 6
},

像这样更改它以帮助它了解异步/等待:

  "ecmaVersion": 2017

答案 2 :(得分:1)

Node.js 8-承诺

按照帖子Cloud Functions for Firebase Async Await style中的建议启用Node.js 8

  1. Set Node.js version Y[i, 1:8] ~ dmnorm(mu[i,], Omega[,])
  2. 使用"engines": {"node": "8"}

    promisify

    const writeFile = util.promisify(fs.writeFile);

Node.js 8之前的版本-手动转换

answer概述了有关将Google语音转换为 TTS 的更具体问题的一种较旧的方法,将回调转换为承诺。

return writeFile(tempFile, response.audioContent, 'binary')

答案 3 :(得分:0)

更改.eslintrc.json中的ecmaVersion

  

“ parserOptions”:{
      //对于某些语法用法是必需的
      “ ecmaVersion”:8
    }

答案 4 :(得分:0)

.eslint.json

“解析器选项”:{ // 某些语法用法需要 “ecmaVersion”:6 }, 像这样改变它以帮助它理解 async/await:

"ecmaVersion": 2017

package.json “脚本”:{ "lint": "eslint 。" }, 改为:

“脚本”:{ "lint": "eslint" },

引用韦伯船长和道格史蒂文森

答案 5 :(得分:0)

ISSUE ES7 你必须把它改成 ES8

  • 2016 年发布的 ES7 没有 async、await 和箭头函数
  • 2017 年发布的 ES8 具有 async、await 和箭头功能

您必须检查您的 .eslintrc 是否至少有 es8 或 2017,这是相同的。

如果文件是 .eslintrc.json

"ecmaVersion": 2017 要么 "ecmaVersion": 8

如果文件是 .eslintrc.js

环境:{ es8:真, 节点:真 }

对某些人来说是这样的

就我而言,它通过更改 package.json 解决了

"scripts": { "lint": "eslint ." },

改为:

"scripts": { "lint": "eslint" },

正如乔纳森所说,但我想知道为什么?

然后意识到我有两个同名的文件

  • .eslintrc.js
  • .eslintrc.json

this is eslintrc.json

this is eslintrc.json

如您所见,在两个同名文件中有不同版本的 ecmaScript,

  • "ecmaVersion": 2017 // 等于文件中的 es8: .eslintrc.json
  • es6: true, // 于 2015 年 6 月在文件:.eslintrc.js 中发布

所以当我们运行时:npm run lint 它使用 es6:true 运行 .eslintrc.js 所以解决这个冲突只是删除.eslintrc.js,因为它有错误的ecmaScript。