这是我的代码:-
exports.uploadImage = (req, res) => {
const BusBoy = require('busboy');
const path = require('path');
const os = require('os');
const fs = require('fs');
const busboy = new BusBoy({ headers: req.headers });
let imageFileName;
let imageToBeUploaded = {};
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
const imageExtension = filename.split('.')[filename.split('.').length - 1];
imageFileName = `${Math.round(Math.random() * 100000000000)}.${imageExtension}`;
const filepath = path.join(os.tmpdir(), imageFileName);
imageToBeUploaded = { filepath, mimetype };
file.pipe(fs.createWriteStream(filepath));
});
busboy.on('finish', () => {
console.log('Busboy on started');
//code breaks here
admin.storage().bucket().upload(imageToBeUploaded.filepath, {
resumable: false,
metadata: {
metadata: {
contentType: imageToBeUploaded.mimetype
}
}
})
.then(() => {
const imageUrl = `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o/${imageFileName}?alt=media`;
console.log('logging image url' + imageUrl);
return db.doc(`/users/${req.user.handle}`).update({ imageUrl })
})
.then(() => {
return res.json({ message: 'Image uploaded successfully' });
})
.catch(err => {
console.error(err);
return res.status(500).json({ error: err.code });
})
});
busboy.end(req.rawBody);
}
我已经提到我的代码在注释中出现的地方,而我得到的错误是Error: Cannot parse response as JSON: Not Found
message: 'Cannot parse response as JSON: Not Found'
错误消息说无法将响应解析为JSON
。这是否意味着Firebase的响应不是JSON?我在请求的标题中有一个令牌,在主体中有一个图像作为表单数据。我真的不知道怎么了,请帮忙
答案 0 :(得分:1)
很不幸,我无法识别JSON解析错误,因此我改写了代码,以简化@robsiemb的工作。
您的uploadImage
函数似乎已配置为某些中间件,因此我在下面做了同样的事情。该代码将使用从Reference.push().key
生成的唯一文件名将上传的数据直接流到Cloud Storage,以防止冲突。
在下面的代码中,
userData/someUserId/images/-JhLeOlGIEjaIOFHR0xd.png
BusBoy
instance。// import Firebase libraries & initialize
const admin = require('firebase-admin');
admin.initializeApp(); // initializes from environment variables
// import required modules
const BusBoy = require('busboy');
exports.uploadImage = (req, res) => {
if (req.method !== 'POST') {
res.sendStatus(405); // 405 METHOD_NOT_ALLOWED
return;
}
let busboy = new BusBoy({headers: req.headers}); // add {limits: {files: 1}} to limit to only a single file upload
let bucket = admin.storage().bucket();
let db = admin.firestore();
let storageFilepath;
let storageFile;
// Note: Currently only the last file is saved to `/users/${req.user.handle}`
busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
let fileext = filename.match(/\.[0-9a-z]+$/i)[0];
storageFilepath = `userData/${req.user.handle}/images/` + getUniqueName() + fileext;
storageFile = bucket.file(storageFilepath);
file.pipe(storageFile.createWriteStream({ gzip: true }));
})
.on('finish', () => {
if (!storageFile) {
res.status(400).json({error: 'expected file'}); // 400 BAD_REQUEST
return;
}
db.doc(`/users/${req.user.handle}`).update({ imagePath: storageFilepath })
.then(() => {
res.status(201).json({ message: 'Image uploaded successfully' }); // 201 CREATED
})
.catch((err) => {
console.error(err);
res.status(500).json({ error: err.code }); // 500 INTERNAL_SERVER_ERROR
});
})
.on('error', (err) => {
console.error(err);
res.status(500).json({ error: err.code });
});
req.pipe(busboy);
});
function getUniqueName() {
// push() without arguments returns a ThennableReference, which we'll abuse for it's key generation
return admin.database().ref().push().key;
}
如果您确实希望公开访问上传的图像,则可以使用以下.on('finish', ...)
处理程序,该处理程序添加到File.makePublic()
函数中:
.on('finish', () => {
if (!storageFile) {
res.status(400).json({error: 'expected file'}); // 400 BAD_REQUEST
return;
}
storageFile.makePublic()
.then(() => {
return db.doc(`/users/${req.user.handle}`).update({
imagePath: storageFilepath,
imageUrl: `https://storage.googleapis.com/${config.storageBucket}/${storageFilepath}`
});
})
.then(() => {
res.status(201).json({ message: 'Image uploaded successfully' }); // 201 CREATED
})
.catch((err) => {
console.error(err);
res.status(500).json({ error: err.code }); // 500 INTERNAL_SERVER_ERROR
});
})
答案 1 :(得分:0)
找到了解决该问题的方法!
本质上-您需要设置Google应用程序凭据。进入firebase并查看您的设置。您需要设置环境变量GOOGLE_APPLICATION_CREDENTIALS,以便在访问这些文件时firebase拥有您的凭据。
https://firebase.google.com/docs/admin/setup?authuser=1了解更多信息。
完成此操作后,请检查Firebase中您要处理的每个区域的安全设置。这应该可以解决问题(绝对是安全问题,而不是您的代码)。
对于那些关注的人来说,这也是该教程。 https://www.youtube.com/watch?v=m_u6P5k0vP0&t=7661s。
答案 2 :(得分:0)
在我的情况下,它配置了错误的存储桶 ID - 更正后我能够上传文件