这是我的代码:-
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?我在请求的标头中有一个令牌,在正文中有一个图像作为表单数据。我真的不知道出了什么问题,请帮忙
不幸的是,我无法识别 JSON 解析错误,因此我改写了代码,使其更加精简,就像 @robsiemb 所回避的那样。
您的
uploadImage
函数似乎被配置为一些中间件,所以我在下面做了同样的事情。此代码将使用从 Reference.push().key
生成的唯一文件名将上传的数据直接流式传输到 Cloud Storage,以防止冲突。
在下面的代码中,
userData/someUserId/images/-JhLeOlGIEjaIOFHR0xd.png
BusBoy
实例配置限制。
// 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
});
})
本质上 - 您需要设置您的 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 .
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if false;
}
}
}