React+Firestore 9でWebアプリを作成する!基本的なCRUD処理の実装。

React+Firestore 9でWebアプリを作成する!基本的なCRUD処理の実装。

この記事では、Firestoreを使ったデータベースの設定や典型的なCRUD処理の実装方法をReactを例にして紹介したい。

いまやWeb・モバイルの開発者にとって定番となったFirebase。バックエンドシステムを一から開発しなくともアプリを実装できる気軽さゆえに使用する機会は増えている。

この機会にその概要と使い方を確認しておくといいだろう。

なお、Firestoreはバージョン9よりCRUD処理の実装方法に変更があった。この記事では、最新バージョンである9に合わせた新しい実装方法を紹介する。

Firestoreとは?

Firebaseはユーザ認証やプッシュ通知といったWebやMobileアプリに必要な様々な機能を提供するWebプラットフォームでありGoogleによって運営されている。

Firestoreはその数あるサービスのうちのひとつで、クラウド上にデータベースを作成し無料で使用することができる。なお、Firestoreはアイテムの構造をあらかじめ指定する必要の無い「スキーマレス」のデータベースである

FirebaseはAngular・React・Vueなどに対応したSDKがあらかじめ用意されており、開発者は手早く必要とする機能を実装することができる。

なお、Firestoreはバックエンドサーバーなしでも使えることが特徴だが、もちろんアプリのバックエンドシステムとともに使用することも可能だ。その際は、Firebase Admin SDKをバックエンド側で使用する。

FirestoreとRealtime Database

Firebaseには、「Firestore」と「Realtime Database」という2種類のデータベース機能が存在する。

Realtime DatabaseはFirestoreが登場する前のデータベース機能であり、後にサービスを終了することが決定している。

既にRealtime Databaseを本番環境で使用している場合を除いて、Firestoreを使用するようにしよう。

FirestoreでのCRUD処理

ここからはCRUD処理の実装について見ていきたい。

なお、CRUDとは以下の英単語の頭文字で、基本的なデータベースへの処理を意味している。

  • Create – データの保存
  • Read – データの取得
  • Update – データの上書き
  • Delete – データを消去する

CollectionとDocument

コードを見る前にFirestoreで使われる用語を簡単に確認しておきたい。

Firestoreは複数のCollectionから成り立っており、それぞれに複数のDocumentが含まれる。

  • Collection – データを束ねる存在(コレクション)。従来のDBではテーブルにあたる。
  • Document – 基本的には人・物などのオブジェクト。従来のDBではデータセットにあたる。

なお、各DocumentなユニークなIDを持つ必要がある。

このIDはアプリ側で指定しなければ自動的に付与される。

FirebaseコンソールのDatebase画面

データを保存する

Firestoreにデータを保存する場合はsetDoc関数、もしくはaddDoc関数を使用する。

いずれの場合も返り値としてDocumentReferenceオブジェクトが返される。

IDを指定する場合

IDをアプリ側で指定してデータを保存する場合はsetDoc関数を使用する。

import { doc, setDoc } from "firebase/firestore"; 

public async createUserBySet(newUser) {
    return await setDoc(doc(db, 'users', newUser.id), newUser);
}

IDを自動生成させる場合

IDをFirestore側で生成したい時はaddDoc関数を使用する。

生成されたIDはDocumentReferenceオブジェクトのidプロパティに生成されたIDが保持されている。

import { collection, addDoc } from "firebase/firestore"; 

public async createUserByAdd(newUser) {
    const userRef = await addDoc(collection(db, 'users'), newUser);
    return userRef.id;
}

データを取得する

次にデータの取得方法を確認する。

コレクションのすべてのデータを取得する

コレクション内のすべてのデータ(Document)を取得したい場合は次のようにgetDocs関数を使用する。

import { collection, getDocs } from "firebase/firestore"; 

public async getAllUsers() {
    const usersSnap = await getDocs(collection(db, 'users'));
    return usersSnap.map(user => user.data());
}

IDを基にデータを取得する

DoceumentのユニークIDを基にデータを取得する際は、getDoc関数を使用する。

import { collection, getDoc } from "firebase/firestore"; 

public async getUserById(userId) {
    const userSnap = await getDoc(db, 'users', userId);
    if (userSnap.exists()) {
       return userSnap.data();
    } else {
       console.log('Not found.');
    }
}

データを上書きする

データを上書きする場合はIDを指定してデータを保存する際と同様にsetDoc関数を使用する。

import { doc, setDoc } from "firebase/firestore"; 

public async updateUser(newUser) {
    await setDoc(doc(db, 'users', newUser.id), newUser);
}

データを消去する

import { doc, deleteDoc } from "firebase/firestore"; 

public async deleteUser(userId) {
    await deleteDoc(doc(db, 'users', userId));
}