■はじめに
普段はVue.js, Nuxt.jsを使っているのですが、Expressで画像アップロードを実装しようとしたらいつもと勝手が違ったのとサーバー側でFirebaseを使う時はFirebase SDKではなくFirebase Admin SDKを使わないといけないことを理解しておらず詰まったのでメモ。
plugins/firebase.js
const admin = require("firebase-admin");
require("dotenv").config();
const ServiceAccount = require("../ServiceAccount.json");
if (admin.apps.length === 0) {
admin.initializeApp({
credential: admin.credential.cert(ServiceAccount),
storageBucket: process.env.FIREBASE_ADMIN_STORAGE_BUCKET
});
}
module.exports = admin;
testRoute.js
const express = require("express");
const multer = require("multer");
const router = express.Router();
const testController = require("../controllers/testController");
const upload = multer({
storage: multer.memoryStorage(),
});
router.post("/", upload.single("file"), listController.list_create_post);
module.exports = router;
testController.js
const admin = require("../plugins/firebase");
const db = admin.firestore();
const bucket = admin.storage().bucket();
const test_create_post = async (req, res) => {
const file = bucket.file(
`thumbnail/${req.file.originalname}`
);
await file.save(req.file.buffer);
};
module.exports = {
list_create_post,
};
create.ejs
<!DOCTYPE html>
<html lang="ja">
<body>
<div class="create-blog content">
<form action="/lists" method="POST" enctype="multipart/form-data">
<label for="file">File:</label>
<input type="file" id="file" name="file" required />
<button>Submit</button>
</form>
</div>
</body>
</html>
おわりに
ExpressとFirebaseで画像アップロードをするには下記が必要なことがわかりました。
①formタグをmultipart/form-dataにする。
②multipart/form-dataの処理ができるmulterをインポートする。
③Firebase SDKではなくFirebase Admin SDKを使用する。
サーバーの方にとっては基本的なことかもしれませんが、フロントだけやってるとこんなところで躓くのかーという感想です。GCSにあげる際はCloud Functionsでとか、そもそもFirestoreは使わないでMongoDBにあげるなど色々あるので試してみたいです。
参考URL