Help us understand the problem. What is going on with this article?

react-dropzone、Express、Firebaseを使った画像のアップロード

components/FileUpload.ts
const onDrop = (acceptedFiles: File[]) => {
     console.log(formData)
 }

return (
     <div>
         <DropZone  onDrop={onDrop}>
             {({getRootProps, isDragActive}) => (
                 <div {...getRootProps()}>
                     {isDragActive ? "Drop it like it's hot!" : 'Drag a file to upload!'}
                 </div>
             )}
         </DropZone>
     </div>
 )

react-dropzoneを使ってこんな感じに書いて、描画された部分に画像をドロップしてみると

lastModified: 1571463132902
lastModifiedDate: Sat Oct 19 2019 14:32:12 GMT+0900 (日本標準時) {}
name: "hoge.PNG"
path: "hoge.PNG"
size: 353348
type: "image/png"
webkitRelativePath: ""

こんな感じのFileっていう型の配列がもらえる。
んじゃあこのデータ配列そのままサーバ側にぶん投げて、サーバ側でfirebase storageにpath指定してあげりゃあ画像のアップロード実装できんじゃん!
って思ってたんだけど、見てわかる通りpathがfullpath(?)になってない。どうしよう...

最終的に、サーバ側に一時的に画像を保存して、そこで生成されたpathをfirebase側に指定してあげたらうまく行った。

そのために、まずはreact-dropzoneから受け取ったFile配列をFormDataとやらに変換して、それをPOSTデータとしてぶん投げた。

components/FileUpload.ts
 const onDrop = (acceptedFiles: File[]) => {
     const formData = new FormData();
     acceptedFiles.forEach(file => {
         formData.append('Files', file)
     })
     dispatch(postFiles.request(formData))
 }

参考にさせていただいたサイト様様 → https://qiita.com/uryyyyyyy/items/9954205a620b6f3c1f24

んで、これをExpress側で受け取るんだけど、このデータはmultipart/form-dataというものらしく、普通にやったらうまく受け取れなかった。なんやそれ。知らんがな。

app.ts
import multer from 'multer';

const upload = multer({ dest: './uploads/' });

app.post('/files', upload.fields([ { name: 'Files' } ]), postStorageController);
controller/postStorageController.ts
export function postStorageController(req: Request, res: Response, next: NextFunction) {
    const files: Express.Multer.File[] = req.files['Files'];

こういう風に書いてあげると、filesの部分で以下のような感じで値がもらえる

[Object: null prototype] {
  Files:
   [ { fieldname: 'Files',
       originalname: 'hoge.PNG',
       encoding: '7bit',
       mimetype: 'image/png',
       destination: 'uploads/',
       filename: 'd18eb9674f13a81898e7c25bb0c3bda6',
       path: 'uploads/d18eb9674f13a81898e7c25bb0c3bda6',
       size: 353348 } ] }

参考にさせていただいたサイト様様 → https://qiita.com/uryyyyyyy/items/9954205a620b6f3c1f24
(さっきと同じ記事。圧倒的感謝)

あとは、Google先生の解説を見ながらfirebase storageにあげれば終わり!

controller/postStorageController.ts
export function postStorageController(req: Request, res: Response, next: NextFunction) {
    const files: Express.Multer.File[] = req.files['Files'];

    files.forEach(fileInfo => {
        const uploadFilePath = `files/${fileInfo.originalname}`
        bucket.upload(fileInfo.path, { destination: uploadFilePath, contentType: fileInfo.mimetype }, error => {
            if (error) {
                console.log(`failed storage post ${fileInfo.originalname}`);
                console.log(error.message);
                return res.sendStatus(404);
            } else {
                console.log(`success storage post ${fileInfo.originalname}`);
                return res.sendStatus(200);
            }
    }
}

↓↓↓今回書いたソースコード

(フロント)
https://github.com/ShotaroOkada/fileupload_react_client

(サーバ)
https://github.com/ShotaroOkada/fileupload_express_api

ShotaroOkada
ポケモン世界王者になったり1年間オナ禁してみたりとよくわからんことしてるので、よかったら遊びに来てください(https://bluestick-believer.hatenablog.com)
https://bluestick-believer.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした