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

最新の記事

2〜3ヶ月と見積もっていた開発期間を、クエリアを導入することでわずか1週間に短縮できました

2012年5月創業のフルカイテン株式会社。 「在庫をフル回転させる」をコンセプトに、機械学習を駆使したSaaS『FULL KAITEN』を提供し、在庫問題の解決に取り組む。

more

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

Querierについて詳しく見る