🚀
(Firebase)ストレージを使って写真をアップロード
写真アップロード機能を実装するにあたって、今まではローカルにしか保存したことがなかったため、今回は Firebase を使ってみることにしました。
🔁 実装の流れ
① Firebase プロジェクトを作成
Firebase コンソールから新しいプロジェクトを作成します。
② Storage を有効化
バケットが自動生成されるので、セキュリティルールを設定します。
(テストモードまたは本番モードのいずれかで開始)
⭐️ユーザー情報確認のためにはFirebaseで認証できる方法ではないといけない。
✅ 本番モード:認証ユーザーのみにアクセス許可
例:
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /images/{allPaths=**} {
// ユーザーだけ読み書き可能
allow read, write: if request.auth != null;
}
}
}
③ Firebase SDK の初期化
自分のアプリを Firebase プロジェクトに登録します。
(私は Web アプリだったので Web を選択)
- SDK 初期化用のファイルを
lib/firebase.ts
に作成
アプリを登録すると、「SDK の設定と構成」の部分にインストール命令と初期化に関する文が出てきます!これをlib/firebase.ts
作成します。
⭐️ セキュリティのため、firebaseConfig
の情報(API KEYなど)は .env
に記述
例:
//直接中身を書かない!
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
};
④ アップロード用コンポーネントを作成
FirebaseのStorageに写真を保存
import { storage } from "@/lib/firebase";
import { getDownloadURL, ref, uploadBytes } from "firebase/storage";
🔹 Firebase ストレージの関数の簡単な説明:
- ref: 保存するパスを指定(例: "images/myphoto.jpg")
- uploadBytes: 指定した場所にファイルをアップロード
- getDownloadURL: アップロードされたファイルのURLを取得(ダウンロードやプレビューに使用)
例:
export default function UploadPhoto() {
const [file, setFile] = useState<File | null>(null);
const [uploading, setUploading] = useState(false);
const [url, setUrl] = useState("");
const handleUpload = async()=>{
if(!file) return alert("Please select a file");
try{//UUIDはimport必要!名前重複防止のためなくてもOKfile.nameだけでいい
const uniqueFileName = `${uuidv4()}_${file.name}`;
const storageRef = ref(storage, `images/${uniqueFileName}`);
const snapshot = await uploadBytes(storageRef, file);
const downloadURL = await getDownloadURL(snapshot.ref);
setUrl(downloadURL);
alert("File uploaded successfully");
}catch(error){
console.error("Error uploading file:", error);
alert("Error uploading file");
}finally{
setUploading(false);
}
}
⑤ アップロード後、URL をサーバーへ保存(API)
アップロードされた画像の URL を取得し、API 経由でサーバー・データベース(photo テーブル)に保存。
例:データーベースの操作はPrismaを使ってます。
export async function POST(req: NextRequest) {
...省略
const body = await req.json(); // {photoUrl, postId}をフロント側から取得
if (!body.photoUrl || !body.postId) {
return new Response("Invalid request", { status: 400 });
}
//PhotoURLをもとに生成
const photo = await prisma?.photo.create({
data:{
filename: body.photoUrl,
postId: body.postId,
userId: user.userId,
}
})
return new Response(JSON.stringify(photo), { status: 201 });
}
Discussion