Skip to main content

firebase_storage_ts_study_004

第4章:Storage参照を作ってみる(refの考え方)🧭📦

この章のゴールはシンプルです👇 「アップロード先の“住所(パス)”を決めて、そこを指す“参照(ref)”を作れるようになる」 です✨


1) refってなに?超ざっくり言うと「住所札」🏷️📍

Reference Concept

Cloud Storage は「バケット(大きな箱)」の中に、/ で区切った階層っぽい見た目でファイルが並びます。 その中の「この場所に置く/この場所を触る」を指定するのが 参照(ref) です🧭

ポイント👇

  • ref は クラウド上のファイルへのポインタ(住所札)みたいなもの
  • ref は 軽いので、必要なだけ作ってOK&何度でも使い回せる💪
  • getStorage() で Storage を取り出して、ref(storage, "path") で参照を作る📍
  • "images/space.jpg" みたいに / 区切りのパスもそのまま書ける🧩

これは公式の考え方そのままです。(Firebase)


2) まずは「パス設計」を決めよう📁🧠(ここが実務力!)

Path Design Tree

このあと Rules(守り) は “パスに対して” 書きます。 つまり、パス設計が良いほど Rules が簡単・安全・事故りにくい!🛡️ 実際、Storage の Rules はパスベースでアクセス制御できるのが強みです。(Firebase)

今回おすすめの基本形(プロフィール画像)🧑‍🎨🖼️

  • 元画像(original) users/{uid}/profile/original/{fileId}.{ext}
  • サムネ(thumb)(将来の拡張用) users/{uid}/profile/thumb/{size}/{fileId}.jpg

ここでの狙い👇

  • users/{uid}/... にするだけで「本人の場所」が一発で分かる👀
  • Rules が書きやすい(request.auth.uid == uid が自然)🔐
  • サムネを後から増やしても整理できる📚

3) ファイル名(fileId)を“衝突しない”ようにする💥🚫

UUID vs Filename

✅ 正解に近いルール(おすすめ)

  • fileId = UUID(ランダムID)
  • 拡張子は file.type(MIME)から軽く推測して付ける(なくても動くけど、付けると運用が楽)🙂

なぜ UUID? 同名アップロード事故が起きないし、推測されにくいし、履歴管理もしやすいからです👍


4) パスに入れてOK/避けたい文字の話🧨🧯(地味に重要)

Path Constraints

Storage の参照パスは柔軟ですが、制限があります👇

  • fullPath の合計は UTF-8で 1〜1024 bytes の範囲
  • 改行(CR/LF)はダメ
  • # / [ / ] / * / ? は他ツールと相性が悪いので避けるの推奨

これは公式の「参照の制限」に書かれてます。(Firebase)

なので、ユーザー入力(表示名とか)をそのままパスに入れるのは基本NG🙅‍♂️ → uid + UUID みたいな“機械的な文字列”が最強です💪


5) 手を動かす:パス生成&ref作成ユーティリティを作る🛠️✨

Ref Creation Code

ここでは「住所(文字列)」と「参照(ref)」を毎回手書きしないために、関数化しちゃいます🙌

src/lib/storageRefs.ts を作成

import { getStorage, ref, type StorageReference } from "firebase/storage";

/** MIME から拡張子をざっくり推測(最低限でOK) */
function guessExtFromMime(mime: string): string {
switch (mime) {
case "image/jpeg":
return "jpg";
case "image/png":
return "png";
case "image/webp":
return "webp";
default:
return "bin";
}
}

/** プロフィール画像(元画像)を置く「パス文字列」を作る */
export function buildProfileOriginalPath(uid: string, file: File): {
fileId: string;
path: string;
} {
const fileId = crypto.randomUUID();
const ext = guessExtFromMime(file.type);
const path = `users/${uid}/profile/original/${fileId}.${ext}`;
return { fileId, path };
}

/** パス文字列から StorageReference を作る(これが “住所札”) */
export function profileOriginalRef(path: string): StorageReference {
const storage = getStorage();
return ref(storage, path);
}

✅ ここで「refの感覚」を掴むミニ実験👀

ref には fullPath / name / bucket などのプロパティがあって、デバッグに便利です。(Firebase)

import { profileOriginalRef, buildProfileOriginalPath } from "./storageRefs";

export function debugRef(uid: string, file: File) {
const { path } = buildProfileOriginalPath(uid, file);
const r = profileOriginalRef(path);

console.log("fullPath:", r.fullPath);
console.log("name:", r.name);
console.log("bucket:", r.bucket);
}

6) “Rulesが書きやすいパス”になってるか?チェック✅🛡️

Rules はパスベースで強く書けます。さらに contentTypesize みたいなメタ情報チェックもできます。(Firebase)

この章では Rules 自体はまだ書かないけど、ここだけ覚えておくと勝ちです👇

  • users/{uid}/... にしておくと、本人だけ書けるが自然に作れる🔐
  • 画像なら後で contentTypeimage/* に制限できる🖼️

(Rules本番は後の章でガッツリやります🔥)


7) AIで“パス設計レビュー”して事故を減らす🤖🔍

ここ、AIめちゃくちゃ相性いいです😎 特に Firebase MCP server を入れておくと、エージェントが Firebase の文脈で作業しやすくなります。 公式でも AntigravityGemini CLI などの MCP クライアント対応が明記されています。(Firebase)

おすすめの投げ方(コピペ用)📝✨

  • 「このパス設計、Rulesで“本人だけ書ける”を最短で書ける?穴ある?」🕵️‍♂️
  • 「サムネ(128/512)を追加する前提で、フォルダ構成を整えて」🧩
  • #[]*? みたいな避けたい文字の対策、どこでやるべき?」🧯

8) AIサービスにもつながる話:画像×AIの“鍵”になるのが path 🗝️🤖🖼️

AI Path Key

後で Firebase AI Logic を使って「画像の説明文(alt)生成」や「タグ付け」をやるとき、 どの画像に対する結果か? を紐づける必要があります。

そのとき、pathfileId が “主キー” になります🔑 しかも Firebase AI Logic はモバイル/ウェブからモデル(Gemini/Imagen)を使うための仕組みとして提供されています。(Firebase)

つまりこの章の「パス設計」って、地味に見えて AI機能の土台でもあるんです🔥


ミニ課題🧠✍️(10分)

  1. 自分のアプリ用に、プロフィール画像のパスを1つ決める📁 例:users/{uid}/profile/original/{fileId}.{ext}

  2. 「サムネも将来作る」として、thumb のパス案も1つ決める🖼️ 例:users/{uid}/profile/thumb/128/{fileId}.jpg

  3. fileId の作り方を文章で説明(UUIDにする理由)🔤


チェック✅(できたら合格!)

  • ref が「住所札」で、ref(storage, "path") で作れると言える🧭(Firebase)
  • users/{uid}/... の形にすると Rules が書きやすい理由が分かる🛡️(Firebase)
  • パスに入れる文字の注意点(長さ・改行・避けたい記号)が言える🧯(Firebase)
  • path / fileId を「履歴・AI・整合性」の軸にできるイメージがある🗝️🤖(Firebase)

次の第5章で、いよいよ 「最小アップロード(upload → URL取得)」 に入って「Storageにファイルが増える瞬間」まで行きます⬆️🔗✨