【開発ブログ】Procom開発日誌:Next.js×Firebaseで写真アップロード&スライダー実装完了までの全記録

こんにちは、Procom開発者の海老氏です。
今日は**SNS連携型プロフィールプラットフォーム「Procom」の開発において、「ユーザー写真アップロード&スライダー表示機能」をNext.js×Firebase(Storage)**で実装した進捗について、4000文字超で赤裸々に綴ります。

この機能は、「自分の活動や世界観を最大5枚の写真でアピールできる」という、Procomの“顔”ともいえるUI。YouTubeやInstagram連携などSNS部分も重要ですが、クリエイターやフリーランスにとって**“見せるプロフィール”**は自己ブランディングの命です。
そんな思いを込めつつ、実装の苦労や解決策、成長の記録をすべて残します。


■ なぜ写真スライダー&アップロード機能が重要なのか?

現代のSNSは「自己紹介文」だけでなく、「写真・ビジュアル」がコミュニケーションの主役です。
特にProcomのターゲットであるYouTuber、ダンサー、パフォーマー、フリー芸人などは、ビジュアルで一瞬にして世界観や個性を伝えたい。
そのため「最大5枚まで」「簡単にアップロード」「スライダーで魅せる」ことが欠かせません。


■ 技術的な課題:Next.js+Firebase時代の画像管理

これまではVanilla JSとFirebase(Firestore/Storage)で実装してきたが、**Next.js(App Router構成)**に移行したことで課題が山積み。

  • クライアント(React)でファイル選択→APIでサーバー側に送る仕組み
  • Next.jsのApp RouterでのAPI設計(/api/uploadPhotos)
  • Firebase Storageへの画像アップロードと公開URL取得
  • StorageとFirestoreの整合性管理
    とくに画像のバリデーションや同時アップロード、即時プレビュー更新など「使いやすさ」と「セキュリティ」「パフォーマンス」のバランスが問われました。

■ 実装ステップ:親子コンポーネント分割で責任範囲を明確に

まずReactの設計方針として、

  • PhotoSliderBlock(親)…ファイル選択・保存UI+画像配列の管理
  • PhotoSlider(子)…画像スライダー本体(object-position調整も)

というようにコンポーネント分割。
この分割が地味に大事で、「アップロード後の状態管理」や「スライダーのobject-position(画像表示位置)調整」をシンプルにできます。


■ コードで解説!画像アップロード~表示までの全体フロー

1. ファイル選択+保存UIの設置(PhotoSliderBlock)

tsxコピーする編集する<form onSubmit={handleUpload}>
  <input
    type="file"
    accept="image/*"
    multiple
    max={5}
    onChange={e => setSelectedFiles(e.target.files)}
  />
  <button type="submit" disabled={!selectedFiles}>保存</button>
</form>

選択した画像(最大5枚)はFormDataでサーバーAPI(/api/uploadPhotos)にPOST。
ここで「即時プレビュー」を実装することも考えましたが、「Storageで保存されたURLでのみスライダー表示」と割り切ることで同期の一貫性を確保。

2. サーバーAPI(/api/uploadPhotos)でFirebase Storage保存

Next.jsのAPI Routeで、

  • FormDataから画像ファイルとuidを受け取る
  • Buffer化してStorageのusers/{uid}/photos/{uuid}.jpgに保存
  • 公開URL生成(バケットがpublicの場合)
  • 必要ならFirestoreのユーザードキュメントにURL配列を反映

という「非同期アップロード+URL配信」パターン。

tsコピーする編集するfor (const file of files.slice(0, 5)) {
  const buffer = Buffer.from(await file.arrayBuffer());
  const filename = `users/${uid}/photos/${uuidv4()}.jpg`;
  const fileRef = bucket.file(filename);
  await fileRef.save(buffer, { contentType: file.type, public: true });
  const url = `https://storage.googleapis.com/${bucket.name}/${filename}`;
  urls.push(url);
}

アップロード後はURL配列をJSONで返し、フロントでスライダーを更新!


■ スライダーの設計とユーザー体験

スライダーUIは1枚目を中央に大きく、前後は斜め回転+半透明で表示するデザイン。
object-positionをrangeスライダーで微調整できるので、被写体の位置に合わせて写真を最適化できます。
このあたりはInstagramやTikTokのUIを徹底分析し、**“プロっぽく見せる体験”**を意識して設計しました。


■ 苦労したポイントとその乗り越え方

1. Next.js App RouterでのFormDataハンドリング

従来のExpressサーバーとは異なり、Next.jsのAPI RouteはFormData/Bufferの処理や型付けに若干クセがあります。
たとえばformData.getAll("photos")で配列取得し、型アサーションでFile型と明示することでエラーを回避。
また、開発環境・本番環境(Vercel/Render等)によってStorageバケットのパスや公開設定も異なるため、.env管理の徹底も大切だと再認識しました。

2. Firebase Storageの公開設定

アップロードした画像を誰でも見られるようにpublic設定を忘れると、URLを返しても「403 Forbidden」で見られないという罠。
Firebase ConsoleでStorageバケットの公開設定(allUsersの読み取り権限)やCORS設定も確認。

3. UIの“即時反映”とUXの両立

「アップロード直後にスライダーを即座に更新」するには、APIから返ってきたStorage URLでsetPhotosし直す必要があります。
バリデーション(最大5枚、画像のみなど)や保存中のローディング表示、エラー処理も徹底。


■ 今日学んだ技術的Tips

  • Next.js×Firebaseでの画像アップロードAPI設計は「FormData→Buffer→Storage」が基本
  • フロント側でのFileList管理やFormData.append()の使い方(multiple対応)
  • サーバー側でのStorage保存パス設計(users/{uid}/photos/
  • 公開URLの組み立て(Firebase Storageの場合、https://storage.googleapis.com/{バケット名}/{パス}
  • 画像スライダーの設計とobject-position調整UI
  • アップロード処理のローディングUI、エラー制御

■ 今後の展望:よりプロフェッショナルなプロフィール体験へ

本日の開発で「Procomの顔」ともいえる写真スライダー+アップロード機能の第一歩が完成しました。
ですが、今後さらに以下の点を強化したいと考えています。

  1. Firestoreとの連携強化
     写真URL+object-positionをFirestoreに保存し、ページ再表示時も“同じ位置・同じ並び”で再現する。
  2. 画像の削除・並び替え対応
     UIから「この写真を削除」「並び順を変更」できるようにし、より柔軟なプロフィール編集を実現。
  3. アップロード画像の圧縮・最適化
     モバイル回線でも軽快に表示できるように、アップロード前の画像リサイズ&圧縮処理を導入予定。
  4. ドラッグ&ドロップ対応UI
     スマホやタブレットからも直感的に画像を追加できるUXへ。
  5. プライバシーやセキュリティ対策
     Storageのアクセス制御やファイル名衝突、ストレージの課金対策も視野に入れて進める。

■ まとめ:小さな進捗の積み重ねが未来をつくる

今回の写真アップロード&スライダー実装は、一見シンプルに見えますが、

  • 「どのタイミングでAPIを呼ぶべきか」
  • 「アップロードと同時にスライダー表示をどう実現するか」
  • 「Firebase Storageのpublic設定やセキュリティ」
  • 「UI/UXの細やかな設計」
    など、考えることは山ほどありました。

でも、ひとつずつ設計を整理し、**「何のためにこの機能を作るのか」**を自分の中で明確にすることで、迷わず進むことができました。


最後に…

このブログをここまで読んでくれた方、本当にありがとうございます。
Procomはまだまだ発展途上ですが、**「すべてのクリエイター・フリーランスが主役になれる場所」**を目指して、日々“細かな工夫と挑戦”を積み重ねています。

技術的な質問や感想、アイディアなど、コメント・DMでお気軽にご連絡ください!
引き続き、明日も成長あるのみ。コツコツやっていきます。

おすすめの記事