Firebase Storage 設定
- Firebase コンソールにアクセス
- プロジェクトを選択
- 下にスクロールして「Storage」を選択
- Blazeプランにアップグレード(ほとんどの人は月額0円)
- 「はじめる」→ロケーション選択(何でもOK)して有効化
- 「ルール」タブで一時的に以下のように変更(開発用):
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
React 側でアップロード処理を追加
firebase.js
//Firebase Storage(画像や動画などのファイル保存サービス)を使うための関数を読み込んでいます。
import { getStorage} from 'firebase/storage';
//Firebase Storage の機能を有効化し、アプリで使えるように外部へエクスポートしています。
export const storage = getStorage(app);
App.js
//アップロード予定の画像ファイル(Fileオブジェクト)を保存するためのステートを定義しています。初期値は null です。
const [image, setImage] = useState(null);
//画像投稿
//Firebase に画像をアップロードしたあとで、その画像の URL をここに代入します。最初は null で初期化。
let imageUrl = null;
if (image) {
//Firebase Storage 上に保存する「ファイルの場所」を指定します。
//images/ フォルダに ファイル名_タイムスタンプ 形式で保存するようにして、名前の衝突を防ぎます
const imageRef = ref(storage, `images/${image.name}_${Date.now()}`);
// 実際に画像ファイルを Firebase Storage にアップロードします。
// uploadBytes() は非同期関数なので await を使います。
const snapshot = await uploadBytes(imageRef, image);
// アップロードされた画像の「公開URL(ダウンロードURL)」を取得し、それを imageUrl に代入します。
imageUrl = await getDownloadURL(snapshot.ref);
}
const newPost = {
text: text,
time: formattedTime,
likes: 0,
user: user?.email,
//新しい投稿オブジェクトにこの imageUrl を含めることで、後で <img> タグで表示できるようになります。
imageUrl,
};
setPosts([newPost, ...posts]);
setText('');
// 投稿後に setText('') でテキストエリアをリセットするのと同じように、setImage(null) でファイルもリセットする
setImage(null);
};
return (
// ファイル選択用の <input> フィールド。ユーザーが画像を選択すると、setImage() により画像ファイルがステート image に保存されます。
<input type="file" onChange={(e) => setImage(e.target.files[0])} />
// 投稿一覧で、画像が含まれている投稿だけ <img> を表示します。post.imageUrl があれば画像が表示されます。
{post.imageUrl && (
<img src={post.imageUrl} alt="投稿画像" style={{ maxWidth: '100%' }} />
)}
);