FirebaseとReactでアプリを作成していたときに、Firestore ウェブバージョン9のサブコレクションを取得する方法を記載した記事が中々なかったのでまとめます。
サブコレクションとは?
Firestoreはリレーショナルデータベースとは構造が違い、ドキュメントとコレクションの組み合わせで構成されています。
リレーショナルデータベースとFirestoreの違い
とあるユーザがいてそのユーザに紐づくブログ記事(複数)があった場合、
リレーショナルデータベースでは「ユーザ」テーブルと「ブログ記事」テーブルがそれぞれあり、ブログテーブルにユーザIDを持つなどして「ユーザ」とそれに紐づく「ブログ記事」を定義すると思います。
Firestoreでは、複数の「ユーザ」というコレクションがあり、個々のユーザの中にそれぞれサブコレクションとして「ブログ記事」があるというイメージです。
FireStoreからサブコレクションを取得する方法
上記で書いた通り「ユーザ」と紐づく「ブログ記事」があるという想定で、ユーザに紐づくブログ記事を取得してみます。
以降のソースは全て、以下の通りinitializeやgetFirestoreでdbを取得した前提のソースです。
ここのdbの取得の方法もあまり記載した記事がなかったので念の為記載します。
import { initializeApp } from 'firebase/app'
import { getFirestore } from 'firebase/firestore'
const firebaseConfig = {
// Firestore上で取得できる固有のconfig値
}
initializeApp(firebaseConfig)
const db = getFirestore()
サブコレクションを全て取得する
import { collection, getDocs } from 'firebase/firestore'
const uid = 'user1' // user1 というIDを持ったユーザであると仮定します。
// 'users'というコレクションの中のユーザ一人を'user1'というIDで一意に特定します。 = ドキュメント
// 'user1'というドキュメントの中の'blogs'というコレクションを全て取得。
const snapShots = await getDocs(collection(db, 'users', uid, 'blogs'))
snapShots.forEach((s) => {
// なんらかの処理
})
サブコレクションの中をさらに一意に特定する
import { doc, getDoc } from 'firebase/firestore'
const uid = 'user1'
const blogId = 'blog1' // 'blog1'というIDを持ったブログが1つあると仮定します。
// 取得したサブコレクションから、更に'blogId'で一意に特定する
const blog = await getDoc(doc(db, 'users', uid, 'blogs', blogId))
const blogData = blog.data()
サブコレクションをソートして取得する
import { collection, getDocs, orderBy, query } from 'firebase/firestore'
const uid = 'user1'
// queryとorderByを使って、ブログの日付の新しい順で並び替えます。
const q = query(
collection(db, 'users', uid, 'blogs'),
orderBy('date', 'desc')
// これ以降にさらにorderByで並び替え条件を追加することも可能。
)
const snapShots = await getDocs(q)
snapShots.forEach((s) => {
// なんらかの処理
})
まとめ
1. コレクションを取得するときはgetDoc s (docの複数形です!)とcollectionを使う
2. ドキュメントを取得する時はgetDocとdocを使う
3. コレクション名の指定 → IDを指定 → サブコレクション名の指定 → IDを指定... の順番で、どんな深いサブコレクションでもコレクション自体やドキュメントを指定できます。
以上です!