前提
Typescriptを使用し、ユーザーが適切なファイル・フォルダをreact-dropzone経由でGoogle Cloud Storageにアップロードできる機能を作成しております。
TypeScript
1// Upload.tsx 2import { FC, useCallback, useState } from 'react'; 3import { useDropzone, FileWithPath } from 'react-dropzone'; 4import { getClient } from '@/Infrastructure'; 5const style = { 6 width: 200, 7 height: 150, 8 border: '1px dotted #888', 9}; 10 11const upload2CloudStorage = async (files: FileWithPath[]) => { 12 if (files) { 13 console.log(files); 14 // getClientは独自のfetch関数で、しっかり動きます 15 const res = await getClient().post('/api/upload', { 16 files, 17 }); 18 } 19}; 20type UploadStatus = 'uploading' | 'completed' | null; 21 22export const Upload: FC = () => { 23 const onDrop = useCallback((files: FileWithPath[]) => { 24 setUploadStatus('uploading'); 25 upload2CloudStorage(files); 26 setUploadStatus('completed'); 27 }, []); 28 const { getRootProps, getInputProps, isDragActive } = useDropzone({ 29 onDrop, 30 }); 31 const [uploadStatus, setUploadStatus] = useState<UploadStatus>(null); 32 const message = (uploadStatus: UploadStatus) => { 33 if (uploadStatus == 'uploading') { 34 return 'アップロード中'; 35 } else if (uploadStatus == 'completed') { 36 return 'アップロードが完了しました'; 37 } else if (isDragActive) { 38 return 'ここにファイルをドロップしてください'; 39 } else { 40 return "Drag 'n' drop some files here, or click to select files"; 41 } 42 }; 43 return ( 44 <div {...getRootProps()} style={style}> 45 <input {...getInputProps()} /> 46 <p>{message(uploadStatus)}</p> 47 </div> 48 ); 49}; 50
TypeScript
1// apiです 2import type { NextApiRequest, NextApiResponse } from 'next'; 3import { Storage } from '@google-cloud/storage'; 4import { FileWithPath } from 'react-dropzone'; 5export default async function handler( 6 req: NextApiRequest, 7 res: NextApiResponse, 8) { 9 if (req.method == 'POST') { 10 // Creates a client 11 const { files }: { files: FileWithPath[] } = req.body; 12 console.log(files); 13 const storage = new Storage({ 14 projectId: process.env.GCP_PROJECT_ID, 15 keyFilename: process.env.GOOGLE_APPLICATION_CREDENTIALS, 16 }); 17 files.forEach(async file => { 18 await storage 19 .bucket(process.env.GCLOUD_STORAGE_BUCKET!) 20 .upload(URL.createObjectURL(file)); 21 }); 22 res.end(); 23 } 24}
発生している問題・エラーメッセージ
- ユーザーがreact-dropzone経由でファイルをドラッグドロップで落とし、FileWithPathオブジェクトを取得する→できている
- Google Cloud Storageにアップロードする方法は、ファイルのパスを指定する方法、メモリからアップロードする方法の2つ。ファイルのパスを指定する方法を試す。参考リンク
- FileWithPathオブジェクトから.pathにてパスを取り出し、実行したものの、なぜかFile not found エラーになる。(取り出したパスは、ローカルホストのルートディレクトリからたどったフルパスではなく、ただのファイル名だった)
- FileWithPathオブジェクトをそのままjson.stringfyでメモリからアップロードしたが、中身がとれない
このような状況です。適切にアップロードできる方法を教えていただきたいです。

あなたの回答
tips
プレビュー