Firestoreに今月と前月のデータがあるか調べる処理を実装した


Nuxt.js+Firebaseを勉強しています。

やりたいこと

月ごとのデータを登録しているのですが、月初にログインしたとき今月分データがないときに前月分データをコピーして今月分データとする機能を実装したいと考えました。
ログインしてすぐにこの判定をしたいので、処理タイミングは mounted とします。

環境

  • Firebase 7.3.0
  • Vue CLI 4.0.5
  • Nuxt.js 2.10.2
  • VuexFire 3.2.0

課題1

Firestoreのドキュメント の「クエリの制限事項」にある通り、Firestoreでは論理 OR クエリを利用できません。

今月分と前月分をWHERE句のOR条件で検索するつもりでしたが、これができないことが分かりました。今月と前月の2回に分けてデータベースにアクセスすることもできますが、できればアクセスは1回で済ませたいです。

課題2

VuexFireを使っています。 computed でマッピングされた情報を mounted で使うことができればいいのですが、これもできませんでした。

this.$store.dispatch をするタイミングは mounted です。この dispath の後に続けてコピー処理を実装すると、dispath 完了よりも先にコピー処理が実行されます。データベースアクセスは非同期だからです。

実装したこと

Firestoreのデータベース構造を以下のようにしました。

コレクション ドキュメント サブコレクション ドキュメント フィールド
notes (userID) pages (年月) (各データ)
notes (userID) index YM (年月)

データを登録するときに、pagesサブコレクションの年月ドキュメントにデータを登録します。これに加えて、indexサブコレクションのYMドキュメントに登録した年月を記録することにしました。
mounted でindexサブコレクションのYMドキュメントを取得することで、どの年月がpagesサブコレクションに登録されているか判断できます。

pages/index.vue
// 省略

<script>
  // 省略

  mounted () {
    if (this.$store.getters['auth/isLoggedIn']) { // ログインしている場合は以下の処理を続行
      let userID = this.$store.getters['auth/getUid'];

      let docRef = db.collection('notes').doc(userID).collection('index').doc('YM');
      let self = this;
      docRef.get().then( function(doc) {
        if (doc.exists) {
          // ドキュメントを取得できたら、ここでチェック&コピー処理
        }
      });
    }
  },

  // 省略
</script>