LoginSignup
28
6

はじめに

firestoreを初めて用いるために調べたところ、version8については多くの記述がありましたが、version9についてはほとんど見つかりませんでした。
そこで、version8のコードを独自に試行錯誤してversion9で利用する方法を簡単にまとめました。

サンプルまとめ

スクリーンショット 2023-06-28 14.56.51.png
以下のサンプルではコレクションmenusと、それぞれ料理名などのフィールドを持ったドキュメントを取り扱います。

sample.js
//コレクションの指定
collection(db, "menus");

/* データベースに追加 */
await addDoc(collection(db, "menus"), //第一引数(追加先コレクション)
    { //第二引数(フィールド群)
        name: "味噌汁", //料理名
        mealtime: "breakfast", //時間帯
        date: { //年月日
            year: 2023, 
            month: 5, 
            day: 6
        },
        createdAt: serverTimestamp(), //更新時刻
    });


/* データベースから読み込み */
(await getDocs(query(
    collection(db, "menus"), //追加先コレクションの指定
    where("name", "==", "味噌汁"), //絞り込み
    orderBy("createdAt") //ソート
)))
.forEach(doc => {
    //要素の処理
    console.log(doc.data()["name"]); //料理名取得
});


/* データベースから削除 */
(await getDocs(query(
    collection(db, "menus"), //追加先コレクションの指定
    where("name", "==", "味噌汁"), //絞り込み
    orderBy("createdAt") //ソート
)))
.forEach(async doc => {
    await deleteDoc(doc.ref); //ドキュメントの削除
});


/* ドキュメントの全体を更新 */
(await getDocs(query(
    collection(db, "menus"), //追加先コレクションの指定
    where("name", "==", "味噌汁"), //絞り込み
    orderBy("createdAt") //ソート
)))
.forEach(async doc => {
    await setDoc(doc.ref, { //全てのフィールドを更新する
        name: "豚汁", //料理名
        mealtime: "dinner", //時間帯
        date: { //年月日
            year: 2023,
            month: 7,
            day: 2
        },
        createdAt: serverTimestamp(), //更新時刻
    });
});


/* ドキュメントの一部を更新*/
(await getDocs(query(
    collection(db, "menus"), //追加先コレクションの指定
    where("name", "==", "味噌汁"), //絞り込み
    orderBy("createdAt") //ソート
)))
.forEach(async doc => {
    await updateDoc(doc.ref, { //一部のフィールドを更新
        "date.month": 7, //月 (ネストされたデータはドット'.'で区切る)
        mealtime: "dinner" //時間帯
        createdAt: serverTimestamp() //更新時刻
    });
});

ドキュメントの生成・追加

addDoc()

新規にドキュメントIDを生成して、指定したコレクションに追加します。

sample.js
addDoc(第1引数, 第2引数);
  • 第1引数: 追加先コレクション
  • 第2引数: 追加する連想配列
add1.js
/* データベースに追加 */

//1.コレクションを取得
const menus = collection(db, "menus");

//2.追加したいデータ構造を作成
const datArr = {
    name: "味噌汁", //料理名
    mealtime: "breakfast", //時間帯
    date: { //年月日
        year: 2023, 
        month: 5, 
        day: 6
    },
    createdAt: serverTimestamp() //更新時刻
}

//3.データベースに追加
await addDoc(menus, datArr);

簡略版 ↓

add2.js
/* データベースに追加 */
await addDoc(collection(db, "menus"), {
    name: "味噌汁", //料理名
    mealtime: "breakfast", //時間帯
    date: { //年月日
        year: 2023, 
        month: 5, 
        day: 10
    },
    createdAt: serverTimestamp(), //記録した日時
});

追加例↓
スクリーンショット 2023-06-28 14.56.51.png

ドキュメントの取得

getDocs()

指定したコレクションの中から複数のドキュメントを取得します。

get1.js
//1.コレクション取得
const menus = collection(db, "menus");

//2.クエリ作成
const q = query(
    menus, //コレクション
    where("name", "==", "味噌汁"), //絞り込み
    orderBy("createdAt") //ソート
);

//3.クエリで指定したドキュメント群取得
const docs = await getDocs(q);

//4.ドキュメント群から一つずつ取り出して処理
docs.forEach(doc => {
    console.log(doc.data()[name]);
});

1.コレクション取得

どのコレクションからドキュメントを取得するかを指定します。

2.クエリ作成

ここで取得したいドキュメントに応じて条件式を記入します。

sample.js
query(第1引数, ...第2引数以降);
  • 第一引数: 取得先コレクション
  • 第二引数以降: 絞り込み条件、ソート条件

[絞り込み] where(第一引数, 第二引数, 第三引数)

  • 第一引数: 比較するフィールド名
  • 第二引数: 演算子 (等号など)
  • 第三引数: 比較する値
ex.js
//nameに"味噌汁"を持つドキュメントを取り出す
where("name", "==", "味噌汁")

//yearが2020年以降のドキュメントを取り出す
where("date.year", ">=", 2020)

[ソート] orderBy(第一引数, 第二引数)

  • 第一引数: ソートのため参照する値
  • 第二引数: 任意で"desc"を指定して降順にする
ex.js
//ドキュメントの作成した記録を参照して古い順にソート
orderBy("createdAt", "desc") //タイムスタンプ降順で

//料理名を参照してアルファベット順(辞書順)にソート
orderBy("name")

3.クエリで指定したドキュメント群取得

変数docsに条件に当てはまった全てのドキュメントが入ります。
これは配列ではないため、forEach()で取り出す必要があります。

4.ドキュメント群から一つずつ取り出して処理

.forEach()を接続し、dogsから順番にデータを取り出して処理します。

EX.簡略版

get2.js
(await getDocs(query(
    collection(db, "menus"), //追加先コレクションの指定
    where("name", "==", "味噌汁"), //絞り込み
    orderBy("createdAt") //ソート
)))
.forEach(doc => {
    //要素の処理
    console.log(doc.data()["name"]); //料理名取得
});

ドキュメントの削除

deleteDoc()

指定したコレクションから指定したドキュメントを削除します。

delete1.js
//1.コレクション取得
const menus = collection(db, "menus");

//2.クエリ作成
const q = query(
    menus, //コレクション
    where("name", "==", "味噌汁"), //絞り込み
    orderBy("createdAt") //ソート
);

//3.クエリで指定したドキュメント群取得
const docs = await getDocs(q);

//4.ドキュメント群から一つずつ取り出して削除
docs.forEach(async doc => {
    await deleteDoc(doc.ref); //ドキュメントの削除
});

流れは最後以外はコレクションの取得方法と同様です。

1.コレクション取得

どのコレクションからドキュメントを取得するかを指定します。

2.クエリ作成

ここで取得したいドキュメントに応じて条件式を記入します。

3.クエリで指定したドキュメント群取得

変数docsに条件に当てはまった全てのドキュメントが入ります。
これは配列ではないため、forEach()で取り出す必要があります。

4.ドキュメント群から一つずつ取り出して削除

.forEach()を接続し、dogsから順番にデータを取り出して削除します。

ex.js
await deleteDoc(doc.ref);

deleteDoc()の引数にdoc.refを指定することでドキュメントを削除します。

EX.簡略版

delete2.js
//データベースから削除
(await getDocs(query(
    collection(db, "menus"), //追加先コレクションの指定
    where("name", "==", "味噌汁"), //絞り込み
    orderBy("createdAt") //ソート
)))
.forEach(async doc => {
    await deleteDoc(doc.ref); //ドキュメントの削除
});

ドキュメントの更新

setDoc()

指定したドキュメントの全てのフィールドを更新します。

set.js
/* ドキュメントの全体を更新 */
(await getDocs(query(
    collection(db, "menus"), //追加先コレクションの指定
    where("name", "==", "味噌汁"), //絞り込み
    orderBy("createdAt") //ソート
)))
.forEach(async doc => {
    await setDoc(doc.ref, { //全てのフィールドを更新する
        name: "豚汁", //料理名
        mealtime: "dinner", //時間帯
        date: { //年月日
            year: 2023,
            month: 7,
            day: 2,
        },
        createdAt: serverTimestamp(), //更新時刻
    });
});

ドキュメント群から一つずつ取り出して全体更新

ex.js
setDoc(doc.ref, { 連想配列 });
  • 第一引数: リファレンス
  • 第二引数: 上書きする連想配列

ドキュメントが保持していた更新前の全てのフィールドを一度リセットして、指定したフィールドに上書きします。

//変更前
{
    name: "味噌汁",
    mealtime: "breakfast",
    date: {
        year: 2023, 
        month: 5, 
        day: 6,
    },
    createdAt: serverTimestamp(),
}

//変更後
{ 
    name: "豚汁", 
    mealtime: "dinner",
    date: {
        year: 2023,
        month: 7,
        day: 2,
    },
    createdAt: serverTimestamp(),
}

updateDoc()

指定したドキュメントの一部のフィールドを更新します。

update.js
/* ドキュメントの一部を更新*/
(await getDocs(query(
    collection(db, "menus"), //追加先コレクションの指定
    where("name", "==", "味噌汁"), //絞り込み
    orderBy("createdAt") //ソート
)))
.forEach(async doc => {
    await updateDoc(doc.ref, { 
        "date.month": 7, //月(ネストされたデータはドット'.'で区切る)
        mealtime: "dinner", //時間帯
        favorite: true, //お気に入り
        createdAt: serverTimestamp(), //更新時刻
    });
});

ドキュメント群から一つずつ取り出して一部更新

ex.js
updateDoc(doc.ref, { 連想配列 });
  • 第一引数: リファレンス
  • 第二引数: 上書き・新規追加する連想配列

指定したフィールドのみ更新します。
ドキュメントが保持していないフィールドが指定された場合、新しくフィールドを追加します。

//変更前
{
    name: "味噌汁",
    mealtime: "breakfast",
    date: {
        year: 2023, 
        month: 5, 
        day: 6
    },
    createdAt: serverTimestamp(),
}

//変更後
{ 
    name: "味噌汁", 
    mealtime: "dinner",
    date: {
        year: 2023, 
        month: 7, 
        day: 6
    },
    favorite: true,
    createdAt: serverTimestamp(),
}

[余談] The query requires an index が出る

クエリの作成にて複数のフィールドを参照する場合、そのクエリは「複合クエリ」と見なされ、何も対処をしないとエラーが出ます。
スクリーンショット 2023-05-10 16.01.43.png (115.6 kB)

このようになった場合このエラーのリンクを踏み、下のような画面に遷移したら「保存」を押しインデックスの追加をします。
しばらくすると、このインデックスが有効になり問題なく動作するようになります。
スクリーンショット 2023-05-10 16.02.03.png (399.2 kB)

おわりに

今回はFirestoreのversion9における基本的な関数を取り扱いました。
紹介した関数だけでもある程度Firestoreを扱うことができると考えます。
version9で苦労されている方のお役に立てれば幸いです。

28
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
6