Firebaseのドキュメント取得
個人開発でドキュメントの取得の仕組みがいまいちピンとこないまま使っているので自分用としてまとめてみることにしました。
初めに
初学者のため、誤りや拙い点があるかと思います。明らかな間違いがあるときにはコメントをいただけると嬉しいです。
ドキュメントとは?
Firestoreで使用する、データベースの"ようなもの"です。
実際にはDB操作する時と勝手がかなり異なり、ドキュメントというファイルにJSON配列のようなデータが格納されているイメージが近しいかと思います。
ファイルの中にファイルを格納することができるので、ネストを深くすることも可能です。
Cloud Firestore は NoSQL ドキュメント指向データベースです。SQL データベースとは違い、テーブルや行はありません。代わりに、データは「ドキュメント」に格納し、それが「コレクション」にまとめられます。
参考コード
以下は書籍に関する登録内容をドキュメントから取得するコードです。ステップバイステップで処理の内容を説明していきます。
const [books, setBooks] = useState<Book[]>([]);
const fetchBooks = async () => {
try {
// データベースからbooksコレクションのデータを取得
const q = query(collection(db, "books"));
// ドキュメントを非同期で取得
const querySnapshot = await getDocs(q);
// 取得したドキュメント配列をオブジェクトに変換
const booksData: Book[] = querySnapshot.docs.map((doc) => ({
...(doc.data() as Book),
id: doc.id,
}));
setBooks(booksData);
await fetchUsers(booksData);
} catch (err) {
setError("データの取得中にエラーが発生しました。");
} finally {
setLoading(false);
}
};
ドキュメントの取得方法
Firestore に特有の関数
query
:特定の条件を満たすデータをデータベースから取得するためのクエリを構築する際に使用
collection
:データベース内の特定のコレクションにアクセスするための参照を作成するために使用
docs
:複数のドキュメントを取得
doc
:ひとつのドキュメントを取得
処理の流れ
-
const q = query(collection(db, "books"));
ではコレクション名がbooksに一致するクエリを呼び出す -
const querySnapshot = await getDocs(q);
にて呼び出したコレクション内のドキュメントを呼び出す -
querySnapshot.docs
は、Firestoreのクエリにマッチしたすべてのドキュメントを含む状態。ドキュメントはネストを含む配列形式になっているので、map()
メソッドを使用して新しい配列に変換 - 各ドキュメントをスプレッド演算子を使用してこのオブジェクトのプロパティを新しいオブジェクトにコピー、
id: doc.id
でドキュメントのIDを新しいオブジェクトに追加 -
map()
メソッド は各ドキュメントから新しいオブジェクトを生成し、これらのオブジェクトからなる新しい配列(booksData
)を返す -
setBooks(booksData);
で書籍データを更新
取り出した情報の画面表示
以下のコードで更新したbooks
を展開できます。
<div className="py-8 m-auto w-11/12">
<h1 className="text-center font-bold text-xl">みんなの積み上げ</h1>
{books.map((book) => (
<div
key={book.id}
className="book-item flex items-center border-2 m-4 p-4"
>
<img
className="rounded-full w-32 h-32 object-cover mr-4"
src={users[book.userId]?.photoURL}
alt={users[book.userId]?.displayName || "プロファイル画像"}
/>
<div className="flex flex-col gap-2">
<h2 className="font-bold">{users[book.userId]?.displayName}</h2>
<p className="font-bold">{book.name}</p>
<p>読了日: {book.date}</p>
</div>
</div>
))}
</div>
最後に
こう見ると結構独特な書き方だな〜と思いました。SQLをしっかり使えるようになりたいので、バックも自分で作れるように頑張ります。