Javascript Firebase云文件上传功能

Javascript Firebase云文件上传功能,javascript,firebase,google-cloud-storage,google-cloud-functions,Javascript,Firebase,Google Cloud Storage,Google Cloud Functions,我有一个云函数,我写这个函数是为了将文件上传到google云存储: const gcs = require('@google-cloud/storage')({keyFilename:'2fe4e3d2bfdc.json'}); var filePath = file.path + "/" + file.name; return bucket.upload(filePath, { destination: file.name }).catch(reason =

我有一个云函数,我写这个函数是为了将文件上传到google云存储:

const gcs = require('@google-cloud/storage')({keyFilename:'2fe4e3d2bfdc.json'});

var filePath = file.path + "/" + file.name;

    return bucket.upload(filePath, {
        destination: file.name
    }).catch(reason => {
            console.error(reason);
    });
我使用
强大
解析上传的文件,并尝试记录上传文件的属性,结果似乎很好;它被上传到一个临时目录
”/tmp/upload_2866bbe4fdcc5beb30c06ae6c3f6b1aa/
,但当我尝试将文件上传到地面军事系统时,出现以下错误:

{ Error: EACCES: permission denied, stat '/tmp/upload_2866bbe4fdcc5beb30c06ae6c3f6b1aa/thumb_ttttttt.jpg'
    at Error (native)
  errno: -13,
  code: 'EACCES',
  syscall: 'stat',
  path: '/tmp/upload_2866bbe4fdcc5beb30c06ae6c3f6b1aa/thumb_ttttttt.jpg' }
我正在使用此html表单上载文件:

<!DOCTYPE html>
<html>
<body>

<form action="https://us-central1-appname.cloudfunctions.net/uploadFile" method="post" enctype="multipart/form-data">
    Select image to upload:
    <input type="file" name="fileToUpload" id="fileToUpload">
    <input type="submit" value="Upload Image" name="submit">
</form>

</body>
</html>

选择要上载的图像:
我通过将文件下载到
tmp
来实现这一点

您将需要:

const mkdirp = require('mkdirp-promise');
然后,在
onChange
中。我创建了
tempLocalDir
如下:

const LOCAL_TMP_FOLDER = '/tmp/';
const fileDir = (the name of the file); //whatever method you choose to do this
const tempLocalDir = `${LOCAL_TMP_FOLDER}${fileDir}`;
然后我使用mkdirp创建临时目录

return mkdirp(tempLocalDir).then(() => {
// Then Download file from bucket.
const bucket = gcs.bucket(object.bucket);
return bucket.file(filePath).download({
  destination: tempLocalFile
}).then(() => {
    console.log('The file has been downloaded to', tempLocalFile);
    //Here I have some code that converts images then returns the converted image
    //Then I use
    return bucket.upload((the converted image), {
        destination: (a file path in your database)
    }).then(() => {
        console.log('JPEG image uploaded to Storage at', filePath);
    })//You can perform more actions of end the promise here

我认为我的代码实现了您试图实现的目标。我希望这有帮助;如果需要,我可以提供更多的代码

我从Firebase支持团队那里得到了一个解决方案

因此,首先:

var filePath = file.path + "/" + file.name;
我们不需要file.name,因为
file.path
是文件的完整路径(包括文件名)

因此,将其改为:

var filePath = file.path;
其次,函数在“form.parse(…)”中的异步工作完成之前终止。这意味着在函数执行结束时,实际的文件上载可能仍在进行中

解决方法是将
form.parse(…)
包装在承诺中:

exports.uploadFile = functions.https.onRequest((req, res) => {
   var form = new formidable.IncomingForm();
   return new Promise((resolve, reject) => {
     form.parse(req, function(err, fields, files) {
       var file = files.fileToUpload;
       if(!file){
         reject("no file to upload, please choose a file.");
         return;
       }
       console.info("about to upload file as a json: " + file.type);
       var filePath = file.path;
       console.log('File path: ' + filePath);
 
       var bucket = gcs.bucket('bucket-name');
       return bucket.upload(filePath, {
           destination: file.name
       }).then(() => {
         resolve();  // Whole thing completed successfully.
       }).catch((err) => {
         reject('Failed to upload: ' + JSON.stringify(err));
       });
     });
   }).then(() => {
     res.status(200).send('Yay!');
     return null
   }).catch(err => {
     console.error('Error while parsing form: ' + err);
     res.status(500).send('Error while parsing form: ' + err);
   });
 });
<>最后,您可能想考虑使用FixBasic的云存储来上传文件而不是云函数。Firebase云存储允许您直接将文件上传到Firebase,这样会更好:

  • 它有访问控制
  • 它具有可恢复的上传/下载功能(适用于连接不良)
  • 它可以接受任何大小的文件,而不会出现超时问题
  • 如果你想在上传文件时触发云功能,你可以 做到这一点,还有更多

  • 看起来你没有这样做的权限。是的,我无法访问我上传的临时文件。如果你使用Firebase的云存储,你还可以使用Knowledge进行文件上传吗?你也可以在本地Firebase服务器上使用它吗?是的,我在google云存储上试用过,效果很好,但我还没有在本地Firebase服务器上试用过。谢谢。你能告诉我你是如何使用Node.js服务器上的强大功能来完成这项工作的吗?上面的代码是云功能的完整代码,如果你已经尝试过这些功能,请检查这里:啊,谢谢。我错过了在承诺中使用的强大!