【Next.js × Firebase】Storageで簡単画像アップロード
はじめに
今までにFIrebaseのサービスであるAuthenticationやFirestoreを紹介してきました。
今回はその第三弾でStorageサービスを利用した画像アップロードを紹介しようと思います。
今までの記事はこちらです!
Firebaseセットアップ
前回の記事で紹介したので省略します。
Strageセットアップ
Strage>始める
セキュリティルールの設定(本番環境を潜ったくしました)
ロケーションの設定(わたしは元々設定してありましたがアジアでテキトーに)
完了!
Firebase+Storage初期化処理
Next.jsの記述に移ります。
config情報はfirebaaseのプロジェクトの設定に記載されているものを環境変数で管理しています。
設定の場所については前回の記事を参考にしてください。
getStorage
をimportしてapp
を引数にいれたものをexportします。
import { initializeApp } from "firebase/app";
import { GoogleAuthProvider, getAuth } from "firebase/auth";
import { getFirestore } from "firebase/firestore";
+ import { getStorage } from "firebase/storage";
// Your web app's Firebase configuration
const firebaseConfig = {
apiKey: process.env.FIREBASE_APIKEY,
authDomain: process.env.FIREBASE_AUTH_DOMAIN,
projectId: process.env.FIREBASE_PROJECT_ID,
storageBucket: process.env.FIREBASE_STRAGE_BUCKET,
messagingSenderId: process.env.FIREBASE_MASSAGING_SENDER_ID,
appId: process.env.FIREBASE_APP_ID,
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Initialize Cloud Firestore and get a reference to the service
export const auth = getAuth(app);
export const db = getFirestore(app);
+ export const storage = getStorage(app);
export const provider = new GoogleAuthProvider();
画像アップロードコンポーネント作成
画像アップロードコンポーネントのUIを作成します。
input要素のtype=fileで作成します。
accept属性で受け入れる拡張子を指定します。
また、複数ファイル選択できるようmultiple属性も付与します。
export const FileUploader = ({ setImage }: FileUploaderProps) => {
// ファイルアップロード処理
const onFileUpload = () => {}
return (
<div>
<input
type="file"
onChange={onFileUpload}
multiple
accept=".png,.jpeg,.jpg"
/>
</div>
);
};
続いてはonChange
属性に渡している、画像がアップロードされた際の関数の中身を記述していきます。
初期化処理でexportしたstorage
と以下をfirebase/storage
からimportして使用します。
import { storage } from "@/lib/firebase/firebase";
import { getDownloadURL, ref, uploadBytes } from "firebase/storage";
ref
ref
はfirebaseのStorageのどこにアップロードするかを指定します。
image/ファイル名.png
になるよう保存場所を指定しました。
const storageRef = ref(storage, `image/${file.name}`);
uploadBytes
uploadBytes
でfirebaseのStorageにアップロードします。
const snapshot = await uploadBytes(storageRef, file);
console.log("Uploaded a blob or file!", snapshot);
getDownloadURL
アップロードに成功したらgetDownloadURL
で画像のurlを取得し、画面側に表示させます。
useStateでsetImagesに複数画像urlを保持し、表示させるようにしています。
const url = await getDownloadURL(storageRef);
全体の実装はこちらです。
複数画像のアップロードに対応するためアップロード処理をループさせます。
const onFileUpload = async (e: React.ChangeEvent<HTMLInputElement>) => {
if (!e.target.files) return;
const files = e.target.files;
if (files.length < 1) return;
const urls: string[] = [];
for (let i = 0; i < files.length; i++) {
const file = files[i];
const storageRef = ref(storage, `image/${file.name}`);
try {
const snapshot = await uploadBytes(storageRef, file);
console.log("Uploaded a blob or file!", snapshot);
try {
const url = await getDownloadURL(storageRef);
urls.push(url);
} catch (urlError) {
console.error("Error getting download URL:", urlError);
}
} catch (uploadError) {
console.error("Error uploading file:", uploadError);
}
}
setImages(urls);
};
画像アップロードしてみる
ファイル選択押下して画像を選択します。
アップロードした画像が表示されました!
Firebaseを確認してみるとアップロードされていそうです。
おまけ
権限エラーが発生【解決】
最初uploadしたところエラーが発生しました。
FirebaseError: Firebase Storage: User does not have permission to access 'image/スクリーンショット 2024-06-16 17.22.15.png'. (storage/unauthorized)
Storageのルールを変更します。
読み書きできない状態から誰でも読み書きできる状態に。
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
- allow read, write: if false;
+ allow read, write: if true;
}
}
}
まとめ
今回はFirebaseのサービス第三弾Storageを紹介しました!
少しでも参考になれば嬉しいです!
AuthenticationやFirestoreの実装例についても解説しているのでぜひ!
Discussion