Querier

TypeScriptでFirestoreのデータ操作をマスターする

2023.07.12に公開 | 2023.07.12に更新

Querier運営

@querier_io@querierinc

「Querier(クエリア)」は社内向け管理画面を圧倒的な速さで、かつビジネスのスケールに合わせて柔軟に構築することができるローコードツールです。

管理画面の構築もWeb上で完結
エンジニアのためのローコードツール

Querierについて詳しく見る

Firebase Firestoreは、クラウドベースのNoSQLデータベースであり、データの追加、取得、更新、削除などの操作を簡単に行うことができます。

この記事では、TypeScriptを使用してFirestoreでのデータ操作を実践的に行う方法について解説します。

セットアップ

Firestoreを使用するには、まずFirebaseプロジェクトを作成し、Firestoreを有効にする必要があります。その後、Firebase SDKをプロジェクトにインストールし、認証情報を設定します。

Firebaseプロジェクトの作成やSDKのインストール方法については、Firebase公式ドキュメントを参照してください。

// firebase.ts
import { initializeApp } from 'firebase/app';

const firebaseConfig = {
  // Firebase SDKの構成オブジェクトを貼り付ける
};

const app = initializeApp(firebaseConfig);
export default app;

スキーマとモデルの作成

Firestoreでは、データの構造をスキーマとして定義することができます。TypeScriptを使用することで、型安全なスキーマを作成することができます。

例えば、以下のようにUserモデルを定義します。

interface User {
  id: string;
  name: string;
  email: string;
}

データの取得

単一ドキュメントの取得

特定のドキュメントを取得するには、docメソッドを使用します。

以下は、IDがuser1のドキュメントを取得する例です。

import { getFirestore, doc, getDoc } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function getUserById(userId: string): Promise<User | undefined> {
  const userRef = doc(firestore, 'users', userId);
  const docSnap = await getDoc(userRef);

  if (docSnap.exists()) {
    const user = docSnap.data() as User;
    return user;
  }

  return undefined;
}

// 使用例
const user = await getUserById('user1');
console.log(user);

詳細なドキュメントの取得方法については、公式ドキュメントを参照してください。

複数ドキュメントの取得

コレクション内のすべてのドキュメントを取得するには、collectiongetDocsメソッドを使用します。

以下は、usersコレクション内のすべてのユーザーを取得する例です。

import { getFirestore, collection, getDocs } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function getAllUsers(): Promise<User[]> {
  const usersRef = collection(firestore, 'users');
  const querySnapshot = await getDocs(usersRef);

  const users: User[] = [];
  querySnapshot.forEach((doc) => {
    const user = doc.data() as User;
    users.push(user);
  });

  return users;
}

// 使用例
const users = await getAllUsers();
console.log(users);

複数のドキュメントを取得する方法については、公式ドキュメントを参照してください。

条件を指定して取得

条件を指定してドキュメントを取得するには、whereメソッドを使用します。

以下は、年齢が18以上のユーザーを取得する例です。

import { getFirestore, collection, query, where, getDocs } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function getUsersByAge(age: number): Promise<User[]> {
  const usersRef = collection(firestore, 'users');
  const q = query(usersRef, where('age', '>=', age));
  const querySnapshot = await getDocs(q);

  const users: User[] = [];
  querySnapshot.forEach((doc) => {
    const user = doc.data() as User;
    users.push(user);
  });

  return users;
}

// 使用例
const users = await getUsersByAge(18);
console.log(users);

条件を指定してドキュメントを取得する方法については、公式ドキュメントを参照してください。

ページングを実装する

大量のドキュメントを取得する場合、ページングを実装することが効果的です。startAfterメソッドを使用して次のページを取得できます。

以下は、ページサイズが10のユーザーリストを取得し、次のページを取得する例です。

import { getFirestore, collection, query, orderBy, limit, startAfter, getDocs } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function getUsersWithPagination(pageSize: number, lastVisible?: DocumentSnapshot): Promise<User[]> {
  const usersRef = collection(firestore, 'users');
  let queryRef = query(usersRef, orderBy('name'), limit(pageSize));

  if (lastVisible) {
    queryRef = queryRef.startAfter(lastVisible);
  }

  const querySnapshot = await getDocs(queryRef);

  const users: User[] = [];
  querySnapshot.forEach((doc) => {
    const user = doc.data() as User;
    users.push(user);
  });

  return users;
}

// 使用例
const pageSize = 10;
let lastVisible: DocumentSnapshot | undefined = undefined;

do {
  const users = await getUsersWithPagination(pageSize, lastVisible);
  console.log(users);

  if (users.length > 0) {
    lastVisible = users[users.length - 1].__snapshot!;
  } else {
    lastVisible = undefined;
  }
} while (lastVisible);

ページングの実装方法については、公式ドキュメントを参照してください。

データの追加

IDを指定しないで追加

自動生成されたIDを使用してドキュメントを追加するには、addDocメソッドを使用します。

以下は、新しいユーザーを追加する例です。

import { getFirestore, collection, addDoc } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function addUser(user: User): Promise<string> {
  const usersRef = collection(firestore, 'users');
  const docRef = await addDoc(usersRef, user);
  return docRef.id;
}

// 使用例
const newUser: User = {
  id: 'user1',
  name: 'John Doe',
  email: 'john@example.com',
};

const userId = await addUser(newUser);
console.log(userId);

ドキュメントの追加方法については、公式ドキュメントを参照してください。

IDを指定して追加

特定のIDを持つドキュメントを追加するには、setDocメソッドを使用します。

以下は、IDがuser1のユーザーを追加する例です。

import { getFirestore, doc, setDoc } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function addUserWithId(userId: string, user: User): Promise<void> {
  const userRef = doc(firestore, 'users', userId);
  await setDoc(userRef, user);
}

// 使用例
const newUser: User = {
  id: 'user1',
  name: 'John Doe',
  email: 'john@example.com',
};

await addUserWithId(newUser.id, newUser);
console.log('User added successfully.');

特定のIDを持つドキュメントを追加する方法については、公式ドキュメントを参照してください。

データの更新

ドキュメントを更新

既存のドキュメントを更新するには、updateDocメソッドを使用します。

以下は、IDがuser1のユーザーの名前を更新する例です。

import { getFirestore, doc, updateDoc } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function updateUserName(userId: string, newName: string): Promise<void> {
  const userRef = doc(firestore, 'users', userId);
  await updateDoc(userRef, { name: newName });
}

// 使用例
const userId = 'user1';
const newName = 'Jane Smith';

await updateUserName(userId, newName);
console.log('User name updated successfully.');

ドキュメントの更新方法については、公式ドキュメントを参照してください。

データの削除

ドキュメントの削除

ドキュメントを削除するには、deleteDocメソッドを使用します。

以下は、IDがuser1のユーザーを削除する例です。

import { getFirestore, doc, deleteDoc } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function deleteUser(userId: string): Promise<void> {
  const userRef = doc(firestore, 'users', userId);
  await deleteDoc(userRef);
}

// 使用例
const userId = 'user1';

await deleteUser(userId);
console.log('User deleted successfully.');

ドキュメントの削除方法については、公式ドキュメントを参照してください。

データ内の一部データを削除

ドキュメント内の一部のデータを削除するには、updateDocメソッドを使用します。

以下は、IDがuser1のユーザーのメールアドレスを削除する例です。

import { getFirestore, doc, updateDoc, FieldValue } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function deleteEmail(userId: string): Promise<void> {
  const userRef = doc(firestore, 'users', userId);
  await updateDoc(userRef, { email: FieldValue.delete() });
}

// 使用例
const userId = 'user1';

await deleteEmail(userId);
console.log('Email deleted successfully.');

データの一部を削除する方法については、公式ドキュメントを参照してください。

コレクションの削除

コレクション内のすべてのドキュメントを削除するには、バッチ処理を使用します。

以下は、usersコレクション内のすべてのドキュメントを削除する例です。

import { getFirestore, collection, getDocs, deleteDoc, query, limit, doc, deleteField, writeBatch } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function deleteAllUsers(): Promise<void> {
  const usersRef = collection(firestore, 'users');
  const querySnapshot = await getDocs(query(usersRef, limit(100)));

  const batch = writeBatch(firestore);
  querySnapshot.forEach((doc) => {
    batch.delete(doc.ref);
  });

  await batch.commit();
}

// 使用例
await deleteAllUsers();
console.log('All users deleted successfully.');

コレクションの削除方法については、公式ドキュメントを参照してください。

トランザクション処理

Firestoreでは、トランザクションを使用して複数のデータ操作をまとめて実行することができます。

以下は、トランザクション内でユーザーの情報を更新する例です。

import { getFirestore, doc, runTransaction } from 'firebase/firestore';
import app from './firebase';

const firestore = getFirestore(app);

async function updateUserWithTransaction(userId: string, newName: string): Promise<void> {
  const userRef = doc(firestore, 'users', userId);

  await runTransaction(firestore, async (transaction) => {
    const docSnap = await transaction.get(userRef);
    if (docSnap.exists()) {
      transaction.update(userRef, { name: newName });
    }
  });
}

// 使用例
const userId = 'user1';
const newName = 'Jane Smith';

await updateUserWithTransaction(userId, newName);
console.log('User name updated with transaction successfully.');

トランザクションの詳細については、公式ドキュメントを参照してください。

さいごに

以上で、TypeScriptを使用してFirestoreのデータ操作をする方法について解説しました。これらの操作を使うことで、Firestoreのデータを効果的に操作できるようになります。

詳細な操作や他の機能については、Firebase公式ドキュメントを参照してください。

「Querier(クエリア)」は社内向け管理画面を圧倒的な速さで、かつビジネスのスケールに合わせて柔軟に構築することができるローコードツールです。

最新の記事

【告知】値の参照時の仕様変更のお知らせ

このたび2024年11月11日に値の参照に関する仕様変更を予定しておりますので詳細について報告いたします。

more

管理画面の構築もWeb上で完結
エンジニアのためのローコードツール

Querierについて詳しく見る