Posted on

Firebase Cloud Firestore 使い方の勘ドコロ

FirebaseのCloud Firestoreを扱う際、本家ドキュメントが充実していて検索すればすぐに出てくるのでそれほど困ることはありません。ただ、最初の入りとしてFiresotreのDocumentって何? となったり、docdocRefcityRefcityDocRefsnapShotdocs など、本家ドキュメントの中でも若干変数名の書き方が異なっていたりします。その為、慣れてくれば大丈夫ですが、慣れるまで毎回どう書くんだっけ?と検索することが多かったので、自分なりに解釈して整理してみました。Firestoreを扱える言語は様々用意されていますが、ここでは、JavaScript(Nuxt.js)を例に進めていきます。(セットアップは省きます)

参照元:https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja

Firestoreの基本的な考え方

基本的な考え方は、正にこの図にあるように「フォルダ(collection)」「ドキュメント(document)」「データ」という構成になっています。

参照元:https://firebase.google.com/docs/firestore/data-model
これをFirestoreの管理画面でみるとこのようになります。

これを「フォルダ(collection)」「ドキュメント(document)」「データ」に当てはめてみるとこのようになります。イメージとしては、本棚にフォルダが並んでいてフォルダを選択するとフォルダの中のファイル一覧がみることができ、あるファイルを選択するとそのファイルに書かれている内容をみることができるという感じです。

◯◯Refとは

本家ドキュメントをみると、◯◯Refという変数がよく出てきます。これはその名の通り「参照」です。つまり本棚にあるフォルダ(collection)やフォルダ内のドキュメントを選択した状態です。この時点ではまだ参照なので取得はしていません。usersコレクションを選択した状態であればuserRefusersコレクションのドキュメントを選択した状態であればuserDocRefといった変数をつけると分かりやすいと思います。(本家ドキュメントではそのようなルール決めはありません。)

userRef = db.collection('users')
userDocRef = db.collection('users').doc('YLu7bG7PcRNYhAg3F6MY')

これらを踏まえて、実際にデータの取得、追加、更新、削除のコードを書いてみます。ここではあえて◯◯Refのように変数を使っています。

コレクション配下のドキュメントデータをすべて取得する

usersコレクションを参照した状態で、get().then()を呼び出すとその時点のドキュメント一覧(snapShot)が取得できます。ドキュメントは1つしか存在しない可能性もありますが、ドキュメント一覧なのでforEachでループすることで全データを取得することができます。ユーザIDはデフォルトでドキュメントに振られるIDです。

const db = firebase.firestore();
let userRef = db.collection('users')
userRef.get().then((snapShot) => {
  snapShot.forEach((doc) => {
    this.users.push({
      user: doc.data(),
      user_id: doc.id
    })
  })
})
ユーザID ユーザ名 ユーザメールアドレス
{{user.user_id}} {{user.user.name}} {{user.user.email}}

参考:https://firebase.google.com/docs/firestore/query-data/get-data?hl=ja

コレクション配下のドキュメントデータをフィルタして取得する

フィルタするのにwhereを利用することができます。whereで対象を絞った後、同様にget().then()を呼び出すとフィルタしたドキュメント一覧が取得できます。

const db = firebase.firestore();
let userRef = db.collection('users')
userRef.where('name', '==', '山田太郎1').get().then((snapShot) => {
  snapShot.forEach((doc) => {
    this.filteredUsers.push({
      user: doc.data(),
      user_id: doc.id
    })
  })
})
ユーザID ユーザ名 ユーザメールアドレス
{{user.user_id}} {{user.user.name}} {{user.user.email}}

参考:https://firebase.google.com/docs/firestore/query-data/get-data?hl=ja

単一のドキュメントデータを取得する

単一のドキュメントデータを取得するには、doc()IDを渡し、get().then()を呼び出すと指定したドキュメントのデータが取得できます。この場合、doc()で単一のドキュメントを指定しているので、取得できるのは一覧ではなく指定したドキュメントの値となります。

const db = firebase.firestore();
let userRef = db.collection('users')
userRef.doc('YLu7bG7PcRNYhAg3F6MY').get().then((doc) => {
  this.user = doc.data()
  this.user.user_id = doc.id
})

これは以下のようにも書くことができます。

const db = firebase.firestore();
let userDocRef = db.collection('users').doc('YLu7bG7PcRNYhAg3F6MY')
userDocRef.get().then((doc) => {
  this.user = doc.data()
  this.user.user_id = doc.id
})
ユーザID ユーザ名 ユーザメールアドレス
{{user.user_id}} {{user.name}} {{user.email}}

参考:https://firebase.google.com/docs/firestore/query-data/get-data?hl=ja

ドキュメントを新規追加する

ドキュメントを新規追加するには、add()またはset()を使います。ドキュメントIDをランダムに完全に新規で作成する場合はadd()を利用します。ドキュメントIDを任意の値に指定したい場合はset()を指定します。set()は、既存のドキュメントIDを指定するとドキュメント全体を更新する処理となります。

const db = firebase.firestore();
let userRef = db.collection('users')
// 完全新規で追加する場合
userRef.add({
  name: '山田花子1',
  email: 'sample1@sample.com'
})
// ドキュメントIDを指定して新規追加する場合
userRef.doc('new-user-id').set({
  name: '山田花子2',
  email: 'sample2@sample.com'
})
// 既存のIDを指定してドキュメントの値を更新する場合
userRef.doc('YLu7bG7PcRNYhAg3F6MY').set({
  name: '山田花子3',
  email: 'sample3@sample.com'
})

参考:https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja

ドキュメントを更新する

ドキュメント全体を上書きせずにドキュメントの一部のフィールドを更新するには、update()を使います。

const db = firebase.firestore();
let userRef = db.collection('users')
userRef.doc('YLu7bG7PcRNYhAg3F6MY').update({
  name: '山田花子1'
})

参考:https://firebase.google.com/docs/firestore/manage-data/add-data?hl=ja

ドキュメントを削除する

ドキュメントを削除するには、特定のドキュメントIDをしていしてdelete()を呼び出します。

const db = firebase.firestore();
let userRef = db.collection('users')
userRef.doc('2YkjKlEoEQtH0tBJnByr').delete()

参考:https://firebase.google.com/docs/firestore/manage-data/delete-data?hl=ja

まとめ

ある程度がっつり書いていけばすぐに慣れますが、ちょこちょこ書いていたので書くたびにドキュメントを参照するというのを何回もやっていたのでまとめてみました。自分なりにまとめたものなので誤っている解釈などがあれば指摘して頂ければ幸いです。