javascript - 通过云功能上传文件 Admin SDK - Broken Files
问题描述
我一直在尝试通过firebase云功能(onRequest方法)将文件(主要是图像)上传到firebase存储。我不得不从它的base64表单上传文件。使用下面的代码,我能够实现它,但上传后文件似乎被破坏了。
const functions = require('firebase-functions');
const admin = require('firebase-admin');
const bucket = admin.storage().bucket();
const database = admin.database();
const express = require('express');
const cors = require('cors');
const safetyLogsAPI = express();
safetyLogsAPI.use(cors({ origin: true }));
safetyLogsAPI.post('/', async (req, res) => {
try {
const {
attachments,
projectId
} = req.body;
const safetyKey = database.ref('safetyLogs')
.child(projectId)
.push().key;
if(attachments && Array.isArray(attachments)) {
if (attachments.length > 0) {
for (let index = 0; index < attachments.length; index++) {
const base64Obj = attachments[index];
const { content, fileName, contentType } = base64Obj;
const stream = require('stream');
const bufferStream = new stream.PassThrough();
bufferStream.end(Buffer.from(content, 'base64'));
const fullPath = `SafetyIncidentLog/Images/${projectId}/${safetyKey}/${fileName}`;
const file = bucket.file(fullPath);
const metadata = {
projectId,
safetyLogId: safetyKey,
createdTimestamp: Date.now(),
systemGenerated: 'false',
fileType: 'Image',
fileName,
path: fullPath
};
bufferStream.pipe(file.createWriteStream({
metadata: {
contentType,
metadata
},
public: true,
validation: "md5"
}))
.on('error', (err) => {
console.log('Error Occured');
console.log(err);
})
.on('finish', () => {
console.log('File Upload Successfull');
});
}
}
}
return res.status(200).send({
code: 200,
message: 'Success'
});
} catch (error) {
console.log(error);
return res.status(500).send({
code:500,
message: 'Internal Server Error',
error: error.message
});
}
});
module.exports = functions.https.onRequest(safetyLogsAPI);
我已经尝试过这种方法,前缀部分data:image/png;base64
存在和消除。在这两种方式中,我都看到了损坏的图像。那么我哪里出错了。有没有更好的方法来制作它?
提前致谢。
另外,我尝试这样做的方法是推荐的方法吗?对于个人资料图片上传和对话图片附件等用例,是否推荐这种方式,还是推荐从客户端直接上传?
解决方案
使用 Cloud Functions HTTP 触发器,只要您向客户端发送响应,请求就会终止并且函数会关闭。任何未完成的异步工作可能永远不会完成。
我在您的代码中看到的是您在上传完成之前发送了响应。我可以看到您的呼叫res.status(200).send()
在您开始上传后立即发生。相反,您的代码应该等到响应完成后再发送响应,可能使用on('finish')
and on('error')
。
推荐阅读
- ios - WKWebView 不接收触摸事件
- postgresql - 如果更新成功(或不成功),则返回列和 1(或 0) - PostgreSQL
- ios - 将信息从通用链接传递到视图控制器
- java - 在java中将对象添加到ArrayList
- amazon-ec2 - 如何将错误处理添加到跳转停止的服务器并继续将脚本运行到下一个实例
- wagtail - 在管理员中创建的 Wagtail 重定向不适用于具有 wsgi 的服务器
- javascript - ASP.NET Core - 控制器未从 Ajax 接收完整的 JavaScript 数组对象
- reactjs - 尝试生成动态表格内容时出错:对象作为 React 子项无效
- button - 未发送不和谐按钮
- android - 清单中设置的广播接收器正在使用自定义权限获得权限拒绝