Vue.jsとFirestoreで非同期通信(vuex)

2021.01.18

見出し画像

毎回非同期の処理になると調べることがあるので、自分用の備忘録用に書いていきます。

今回はaxiosを使わない方法になります。

FirestoreのonSnapshotメソッドがめちゃくちゃ便利って話。

目次

  1. 参考にしたサイト
  2. 保存
  3. 取得
  4. Vueに戻って。。。
  5. 実装してみて

参考にしたサイト

Cloud Firestore でリアルタイム アップデートを入手する  |  Firebasefirebase.google.comfirestore, vue.jsでリアルタイム同期のチャットを実装してみる [チュートリアル形式] – Qiita以前までは、リアルタイム同期のwebアプリ※はwebsockets等を使用しなくては実現できませんでした。 でも今の時代にqiita.com

axiosをまだ使用したことがないので、わかりませんがaxiosの使い方が載っている記事を見ると”なんか記述多そうだな〜”と感じてしまいます。

今回はコメントを投稿した時に非同期で表示されるような仕組みです。

まずはfirestoreを使用出来るようにします。ファイルはfirebase.js。

import firebase from 'firebase'  
import 'firebase/firestore' 
import "@firebase/auth"
import 'firebase/database'

var firebaseConfig = {
 apiKey: "unknown",
 authDomain: "unknown",
 databaseURL: "unknown",
 projectId: "unknown",
 storageBucket: "unknown",
 messagingSenderId: "unknown",
 appId: "unknown",
 measurementId: "unknown"
};
firebase.initializeApp(firebaseConfig);
export default firebase.firestore()

firebaseConfigはfirebaseの設定で取得できます。中身は各自自分のものを入れるようにしてください。

保存

次は実際にコンポーネントファイルで入力された値をdispatchを使用してstoreに飛ばしましょう。viewの方は書いてません。

下のコードの説明。commentっていうのに値が入力され、cretaeCommentメソッドが呼び出されるようになっている。

this.commentで入力された中身をcommentに代入。実引数にcommentを持ってdispatchを使用してvuexのactionsの処理を呼び出す。

data() {
   return {
     comment: ''
   }
 }
cretaeComment() {
     let comment = this.comment
     this.$store.dispatch('commentCreate', comment)
     this.comment = ''
   }

下のコードは投稿に関する処理と一覧表示に関する処理に分かれている。

投稿の方から。dispatchで呼び出されたcommentCreateがcommitでmutationsに設定されてあるcreateを呼び出している。この時に実引数には入力されたコメントの値が入っている。

commitで呼び出されたcreateの中身でdb.collectionを使いどのテーブルに保存している。

非同期処理の場合は今回のような流れになっている。vueファイルで入力,dispatchでactionsの処理呼び出し、actionsからmutationsまでcommitで処理呼び出す。呼び出されたmutationsの中の処理で実際にfirestoreに値を保存。

import Vue from 'vue'
import Vuex from 'vuex'
import firebase from 'firebase/app' 
import "@firebase/auth"

Vue.use(Vuex)
state: {
  comments: []
},
mutations: {
 create(state, comment) {
       db.collection('comments').add({
         comment: comment
       })
       .then(() => {
         console.log('完了')
       })
       .catch(err => {
         console.log('ミス', err)
       })
       console.log(comment)
     },
     get(state, comments) {
       state.comments = comments
     }
},
actions: {
     commentCreate({commit}, comment) {
       commit('create', comment)
     },
     getComments({commit}) {
       db.collection('comments').onSnapshot(snapshot => {
         let comments = []
         snapshot.forEach(element => {
           let comment = element.data()
           comment.id = element.id
           comments.push(comment)
         })
         commit('get', comments)
       })
     }
}

取得

保存が完了したので次は一覧表示。今回のポイントはonSnapshotこのメソッドが非常に良い役割をしてくれる。

コメントを取得する際にonSnapshotを使う。リアルタイムリスナーと言って変更を検知することが可能。なので、createやupdateやdeleteなんかにも使える。

今回はaxiosより簡単に出来そうな雰囲気だったので使用することにしました。

onSnapshotを使用して取得したコメントたちをcommitを使ってmutationsに飛ばします。

mutationsではstate.commentsに取得したコメントたちを追加する処理を行なっています。

Vueに戻って。。。

ライフサイクルメソッドを使用してcreated()で先ほど設定した取得する処理を実行させています。

実行した後にはstateのcommentsに値が入っているはずなのでstateから値を取得しています。

取得できたらあとはv-forを使って表示させるだけ。

<template>
    <div v-for="comment in getComments" :key="comment.id">
         <p>{{comment.comment}}</p>
    </div>
</template>

省略。。
created() {
   return this.$store.dispatch('getComments')
 },
 computed: {
   getComments() {
     return this.$store.state.comments
   }
 }

実装してみて

onSnapshot使えて、非同期ってこんな楽に出来るの!?って嬉しくなりましたw

Firestoreいろいろ出来そうなので、これからも勉強していこうと思います。

基本的に編集や削除といった機能も同じ流れで作れるので便利だと思います。

ただ、axiosの事も知っておきたいな〜という気持ちはあります。どのくらい違うんだろ。実装した事ない目線から言うと、記述多そう〜って感じですw

次は記事にコメントしたユーザーを取得する実装を書きたいなと。今はcomment.user_idでidは取れるよになったけど別テーブルにあるユーザーどうやって取ろうって感じのところです。Firestoreの良い勉強にもなりそうです。

外部キーみたいな感じで、railsやlaravelのアソシエーションみたいに取ってこれないかな〜って思ってます。まだ全くわかリマセンw

って感じです。

以上!