
Firebase Firestore は、スケーラブルかつリアルタイムな NoSQL データベースとして、多くのモダンアプリで利用されています。特に Next.js や React、Vue.js などのモダンフロントエンドとの相性がよく、スタートアップや個人開発にも人気です。
本記事では、Firestore設計の中でも「UIDベースの管理」に焦点を当て、そのメリット・注意点・よくあるエラーについて解説します。特に Procom のようなユーザー中心のSNSサービスを開発している方にとって、有益な内容になっています。
Contents
UIDベースとは?
Firestore における UID(User ID)とは、Firebase Authentication などを使って取得される一意の識別子です。これをそのまま Firestore のドキュメントID として利用する設計を UIDベースと呼びます。
/users/{uid}/profile
/users/{uid}/settings
/users/{uid}/events
このように users コレクションに UIDをキーとするサブドキュメント・サブコレクションを持たせる構成です。
なぜ UIDベースが好まれるのか(メリット)
✅ データの一意性を担保できる
UIDは認証時に Firebase 側が一意に生成するため、ユーザー名の重複や衝突の心配がありません。
✅ セキュリティルールをシンプルにできる
Firestoreのセキュリティルールでは、次のような形で「自分のUIDと一致しているドキュメントのみ許可」と記述できます:
match /users/{userId} {
allow read, write: if request.auth != null && request.auth.uid == userId;
}
→ ユーザー単位で自動的にアクセス制限できるのが強みです。
✅ ドキュメントの取得が高速
ドキュメントIDに UID を使うことで、getDoc(doc(db, "users", uid)) のように一発で取得でき、インデックスも不要です。
UIDベース設計の注意点(落とし穴)
⚠️ 「username」をURLに使いたい場合に不便
URLを /user/uid12345 にしたくない!という場合:
/user/taro_yamada
のように「ユーザー名」をURLに使いたい開発者は多いです。しかし、UIDベースだとこのルーティングが複雑になります。
→ 解決策:Firestoreで username → uid のマッピングを別に持つ
/usernames/{username} → { uid: xxx }
⚠️ Cloud Functionsや複数コレクションとの整合性
たとえばユーザー退会時に、/users/{uid} や /favorites/{uid}、/comments/{uid} などを一括削除したいとき、コレクション分割の設計次第で難易度が上がります。
→ 解決策:削除時は Cloud Functions を使ってトリガー削除、または関連UIDドキュメントをまとめて設計する。
Firestore 設計のベストプラクティス
① データ構造はできるだけ浅く
Firestore は「深いネスト」より「平坦な構造」が高速に動作します。
NG:
/users/{uid}/settings/preferences/display/theme
OK:
/users/{uid}/settings → { theme: 'dark' }
② リストデータはサブコレクションで持つ
以下のような「予定一覧」などはサブコレクションが最適です。
/users/{uid}/events/{eventId} → { title, date }
→ 100件以上のリストでもスケーラブルです。
③ 更新頻度の高いデータは別コレクションで管理
プロフィール(滅多に更新しない)と「ログイン履歴」などの頻繁に書き換わるデータを同じドキュメントに入れると、読み取りコストやレイテンシが悪化します。
→ 分離しましょう。
よくあるエラーと対策
❌ Missing or insufficient permissions エラー
原因:セキュリティルールの未設定 or 誤設定
- Firestoreルールが
request.auth.uid != resource.idになっていないか? - ローカル環境で
firebase loginを忘れていないか?
✅ 解決策:
allow read, write: if request.auth != null && request.auth.uid == userId;
❌ Property contains an invalid nested entity エラー
原因:Firestore に空配列や undefined が送られている
✅ 対策:送信前に undefined や空オブジェクトを削除する
const cleanData = JSON.parse(JSON.stringify(data));
❌ permission-denied or 403 本番のみ発生
原因:本番(Render/Vercel)で cookie やセッションが送られていない
✅ 対策:
- Cookie Secure フラグを環境で切り替える
trust proxyを Express で設定する
まとめ
Firestore を UID ベースで設計することは、ユーザー管理が中心となるアプリにおいて非常に合理的なアプローチです。
ただし、その構成ゆえに URL設計や削除ロジックに注意が必要であり、サブコレクションの使い方やセキュリティルール設計も慎重に行う必要があります。
Procom のようなユーザー発信型プラットフォームを構築する際には、ぜひこの記事の内容を参考にして、安全かつ効率的なFirestore構築を目指してください。









