はじめに
firestoreを初めて用いるために調べたところ、version8については多くの記述がありましたが、version9についてはほとんど見つかりませんでした。
そこで、version8のコードを独自に試行錯誤してversion9で利用する方法を簡単にまとめました。
サンプルまとめ
以下のサンプルではコレクションmenusと、それぞれ料理名などのフィールドを持ったドキュメントを取り扱います。
//コレクションの指定
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を生成して、指定したコレクションに追加します。
addDoc(第1引数, 第2引数);
- 第1引数: 追加先コレクション
- 第2引数: 追加する連想配列
/* データベースに追加 */
//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);
簡略版 ↓
/* データベースに追加 */
await addDoc(collection(db, "menus"), {
name: "味噌汁", //料理名
mealtime: "breakfast", //時間帯
date: { //年月日
year: 2023,
month: 5,
day: 10
},
createdAt: serverTimestamp(), //記録した日時
});
ドキュメントの取得
getDocs()
指定したコレクションの中から複数のドキュメントを取得します。
//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.クエリ作成
ここで取得したいドキュメントに応じて条件式を記入します。
query(第1引数, ...第2引数以降);
- 第一引数: 取得先コレクション
- 第二引数以降: 絞り込み条件、ソート条件
[絞り込み] where(第一引数, 第二引数, 第三引数)
- 第一引数: 比較するフィールド名
- 第二引数: 演算子 (等号など)
- 第三引数: 比較する値
//nameに"味噌汁"を持つドキュメントを取り出す
where("name", "==", "味噌汁")
//yearが2020年以降のドキュメントを取り出す
where("date.year", ">=", 2020)
[ソート] orderBy(第一引数, 第二引数)
- 第一引数: ソートのため参照する値
- 第二引数: 任意で
"desc"
を指定して降順にする
//ドキュメントの作成した記録を参照して古い順にソート
orderBy("createdAt", "desc") //タイムスタンプ降順で
//料理名を参照してアルファベット順(辞書順)にソート
orderBy("name")
3.クエリで指定したドキュメント群取得
変数docsに条件に当てはまった全てのドキュメントが入ります。
これは配列ではないため、forEach()
で取り出す必要があります。
4.ドキュメント群から一つずつ取り出して処理
.forEach()
を接続し、dogsから順番にデータを取り出して処理します。
EX.簡略版
(await getDocs(query(
collection(db, "menus"), //追加先コレクションの指定
where("name", "==", "味噌汁"), //絞り込み
orderBy("createdAt") //ソート
)))
.forEach(doc => {
//要素の処理
console.log(doc.data()["name"]); //料理名取得
});
ドキュメントの削除
deleteDoc()
指定したコレクションから指定したドキュメントを削除します。
//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から順番にデータを取り出して削除します。
await deleteDoc(doc.ref);
deleteDoc()
の引数にdoc.ref
を指定することでドキュメントを削除します。
EX.簡略版
//データベースから削除
(await getDocs(query(
collection(db, "menus"), //追加先コレクションの指定
where("name", "==", "味噌汁"), //絞り込み
orderBy("createdAt") //ソート
)))
.forEach(async doc => {
await deleteDoc(doc.ref); //ドキュメントの削除
});
ドキュメントの更新
setDoc()
指定したドキュメントの全てのフィールドを更新します。
/* ドキュメントの全体を更新 */
(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(), //更新時刻
});
});
ドキュメント群から一つずつ取り出して全体更新
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()
指定したドキュメントの一部のフィールドを更新します。
/* ドキュメントの一部を更新*/
(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(), //更新時刻
});
});
ドキュメント群から一つずつ取り出して一部更新
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 が出る
クエリの作成にて複数のフィールドを参照する場合、そのクエリは「複合クエリ」と見なされ、何も対処をしないとエラーが出ます。
このようになった場合このエラーのリンクを踏み、下のような画面に遷移したら「保存」を押しインデックスの追加をします。
しばらくすると、このインデックスが有効になり問題なく動作するようになります。
おわりに
今回はFirestoreのversion9における基本的な関数を取り扱いました。
紹介した関数だけでもある程度Firestoreを扱うことができると考えます。
version9で苦労されている方のお役に立てれば幸いです。