そもそもFirestoreとは
- FirestoreはGoogle Cloudが提供するNoSQLドキュメントデータベース
- Firebaseの一つの機能
Firebaseとは
- Googleが提供している
mBaaS
(mobile Backend as a Service) - DBやバックエンド、デプロイなどの機能を提供してくれるサービス
- バックエンドを作らず、Webアプリやモバイルアプリを作ることができる
用語
用語 | 意味 |
---|---|
コレクション | データテーブル的なもの |
ドキュメント | レコード的なもの |
フィールド | カラム的なもの |
サブコレクション | データテーブルの中にネストしたデータテーブル |
特徴
Firestoreが提供しているクエリにはテーブル結合機能が無い
コレクション(データテーブル)をテーブル結合するための機能はFirestoreは提供していない。代わりにコレクションの中にコレクションを追加できるサブコレクション
機能がある。
デフォルトのデータベース
Firestoreを利用すると自動的にデフォルトのデータベースとしてdefalut
が用意される
Reactで使うための準備
1.firebaseの初期化
src/db/firebase.ts
import { initializeApp } from "firebase/app";
import { getFirestore } from "firebase/firestore";
import { getAuth } from "firebase/auth";
const firebaseConfig = {
apiKey: "xxxxxxxx",
authDomain: "my-app.firebaseapp.com",
projectId: "my-app",
storageBucket: "my-app.firebasestorage.app",
messagingSenderId: "xxxxxx",
appId: "xxxxxx",
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getFirestore(app);
const auth = getAuth(app);
export { db, auth };
データの取得
データの取得はdocument
参照インスタンスからしか取得できない
ドキュメントIDを指定してドキュメントを取得
import { db } from "@/db/firebase";
import { doc, getDoc } from "firebase/firestore";
const collectionName = "users";
const docId = "user-1";
// ドキュメント参照インスタンスを指定
const docRef = doc(db, collectionName, docId);
// ドキュメント情報を取得
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
console.log("Document data:", docSnap.data());
} else {
console.log("No such document!");
}
サブコレクションのドキュメントを取得
import { db } from "@/db/firebase";
import { doc, getDoc } from "firebase/firestore";
// userドキュメントの中のtodos(サブ)コレクションからtodoドキュメントを取得
const userId="user-1";
// userドキュメントの参照
const userRef = doc(db, "users", userId);
// サブコレクションの参照
const todosRef = collection(userRef, "todos");
const todoId="todo-1";
// todoドキュメントの参照
const todoRef = doc(todosRef, todoId);
// ドキュメント情報を取得
const docSnap = await getDoc(todoRef);
if (docSnap.exists()) {
console.log("Document data:", docSnap.data());
} else {
console.log("No such document!");
}
サブコレクションのドキュメントを指定する際に、ファイルパスのように指定することで短くできる。
const userId="user-1";
const todoId="todo-1";
const todoRef = doc(db, `users/${userId}/todos`, todoId);
/* 上記は下記と同じこと*/
// const userRef = doc(db, "users", userId);
// const todosRef = collection(userRef, "todos");
// const todoRef = doc(todosRef, todoId);
フィールド情報で条件検索しドキュメントを取得
import { db } from "@/db/firebase";
import { doc, getDocs, query, where } from "firebase/firestore";
const userId = "user-1";
// ドキュメント参照インスタンスを指定
const usersRef = doc(db, "users", userId);
// クエリを作成
const q = query(usersRef, where("name", "==", ken));
// クエリ実行
const docsSnapshot = await getDocs(q);
if (docsSnapshot.empty) {
console.log("No such document!");
} else {
docsSnapshot.docs.forEach((doc) => {
console.log(doc.id, " => ", doc.data());
})
}
データの追加
ドキュメントの追加(ID指定)
ドキュメントIDを指定して追加する場合はsetDoc
関数を使う
ドキュメントの追加(ID指定)
import { db, setDoc, FirestoreError } from "@/db/firebase";
interface UserState {
userId: string;
userName: string;
mail: string;
}
export const createUser = async ({ userId, ...userData }: UserState): Promise<void> => {
const collectionName = "users";
// コレクション参照インスタンスの取得
const userCollectionRef = collection(db, collectionName);
// 追加ドキュメントインスタンス取得
const addDocRef = doc(userCollectionRef, userId);
try {
// ドキュメント追加
await setDoc(addDocRef, userData);
} catch (error) {
if (error instanceof FirestoreError) {
console.error("Error adding document: ", error.message);
}
}
};
クエリ演算子
クエリの条件指定
AND条件
export const queryAnd = async () => {
const userId = "user-1";
const usersRef = collection(db, `users/${userId}`);
const q = query(usersRef, where(name, "!=", "KEN"), where("mail", "==", "test@sample.com"));
const docsSnap = await getDocs(q);
};
OR条件
export const queryOr = async () => {
const userId = "user-1";
const usersRef = collection(db, `users/${userId}`);
const q = query(usersRef,
or(where(name, "!=", "KEN"), where("mail", "==", "test@sample.com")));
const docsSnap = await getDocs(q);
};
指定したdocumentID以外のドキュメントを取得
import {collection, query, where,getDocs documentId } from "firebase/firestore";
export const queryOtherDocumentId = async () => {
const userId = "user-1";
const usersRef = collection(db, `users`);
// documentIDを検索条件に使う場合はdocumentId()を使う
const q = query(usersRef, where(documentId(), "!=", userId));
const docsSnap = await getDocs(q);
};