Node.js管理后台如何向Firebase已有的Articles集合按指定结构上传图片
实现方案
前置准备
首先安装Firebase Admin SDK用于操作Firestore数据库:
npm install firebase-admin
在你的../config/目录下新增Firebase Admin初始化配置,示例如下:
// ../config/firebaseAdmin.js const admin = require('firebase-admin'); // 从Firebase控制台下载服务账号密钥JSON文件导入即可 const serviceAccount = require('./你的服务账号密钥文件名.json'); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), storageBucket: '你的Bucket名称' // 和你之前使用的bucketname保持一致 }); const db = admin.firestore(); module.exports = { admin, db };
调整说明
你需要同时完成两项核心调整才能匹配现有结构:
- 调整Cloud Storage的文件存储路径,匹配要求的层级结构
- 图片上传成功后,往Firestore的对应子集合写入图片记录,供Flutter端的StreamBuilder监听读取
完整修改后代码
const express = require('express') const bodyParser = require('body-parser') const multer = require('multer') const util = require('util') const gc = require('../config/') const bucket = gc.bucket(bucketname) // 引入刚才配置的Firestore实例 const { db } = require('../config/firebaseAdmin') const app = express() const multerMid = multer({ storage: multer.memoryStorage(), limits: { fileSize: 5 * 1024 * 1024, }, }); app.disable('x-powered-by') app.use(multerMid.single('file')) app.use(bodyParser.json()) app.use(bodyParser.urlencoded({extended: false})) const { format } = util // 给uploadImage方法新增postId参数 const uploadImage = (file, postId) => new Promise((resolve, reject) => { const { originalname, buffer } = file // 调整文件存储路径为 articles/{postId}/images/文件名 const fileName = originalname.replace(/ /g, "_") const blob = bucket.file(`articles/${postId}/images/${fileName}`) const blobStream = blob.createWriteStream({ resumable: false }) blobStream.on('finish', () => { const publicUrl = format( `https://storage.googleapis.com/${bucket.name}/${blob.name}` ) resolve(publicUrl) }) .on('error', () => { reject(`Unable to upload image, something went wrong`) }) .end(buffer) }) app.post('/uploads', async (req, res, next) => { try { const myFile = req.file // 从请求的formData中获取对应帖子的postId const postId = req.body.postId if (!postId) { return res.status(400).json({message: '缺少postId参数'}) } const imageUrl = await uploadImage(myFile, postId) // 上传成功后往Firestore对应子集合写入记录 await db.collection('articles').doc(postId).collection('images').add({ url: imageUrl, createdAt: new Date(), // 可按需补充其他字段,比如文件名、文件大小等 fileName: myFile.originalname }) res .status(200) .json({ message: "Upload was successful", data: imageUrl }) } catch (error) { next(error) } }) app.use((err, req, res, next) => { res.status(500).json({ error: err, message: 'Internal server error!', }) next() }) app.listen(9001, () => { console.log('app now listening for requests!!!') })
前端调用要求
管理后台调用上传接口时,使用FormData格式传递参数,除了file字段外,额外增加postId字段传入对应帖子的ID即可。
内容的提问来源于stack exchange,提问作者Awesome Bassey
相关产品推荐
相关产品推荐

