PROGRAMMING

Slackクローンチャット機能【Vue.js】

今日の内容
・onSnapshotメソッド
・メッセージを時系列順にする

学習内容

onSnapshotメソッド

Slackのようにリアルタイムでチャットをするには、リアルタイムでアップデートをしていく必要があります。

リロードをせずにリアルタイムでアップデートをするには、onSnapshotというメソッドを使います。

pages/channels/_id.vueファイルを変更していきます。

<script>
import Messages from '~/components/Messages.vue'
import ChatForm from '~/components/ChatForm.vue'
import { db } from '~/plugins/firebase'

export default {
  components: {
    Messages,
    ChatForm,
  },
  data() {
    return {
      messages: [],
    }
  },
  mounted() {
    const channelId = this.$route.params.id
    db.collection('channels')
      .doc(channelId)
      .collection('messages')
      .get()
      .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
          this.messages.push({ id: doc.id, ...doc.data() })
        })
      })
  },
}
</script>

上のは現在のファイルの状態ですが、これをonSnapshotを使って、下記を参考に変更していきたいと思います。

.onSnapshot(function(snapshot) {
        snapshot
.docChanges().forEach(function(change) {
           
if (change.type === "added") {

この部分を使って、 ドキュメントが追加された時にデータが更新されるようにします。

下記のように変更してみます。

<script>
import Messages from '~/components/Messages.vue'
import ChatForm from '~/components/ChatForm.vue'
import { db } from '~/plugins/firebase'

export default {
  components: {
    Messages,
    ChatForm,
  },
  data() {
    return {
      messages: [],
    }
  },
  mounted() {
    const channelId = this.$route.params.id
    db.collection('channels')
      .doc(channelId)
      .collection('messages')
      .onSnapshot((snapshot) => {
        snapshot.docChanges().forEach((change) => {
          const doc = change.doc
          if (change.type === 'added') {
            this.messages.push({ id: doc.id, ...doc.data() })
          }
        })
      })
  },
}
</script>

上から読んでいくと。

.onSnapshotでは、メッセージで変更があった場合、処理を実行するようになっています。

snapshot.dccChanges()では、データベースの変更点を取得します。snapshotとは、ある時点のデータベースの情報を抜き取ったもののようなもののことです。

詳しくは下記を参照してください。

そして、データベースの変更点を取得したので、それをforEach文で実行していきます。

const doc = change.docでは、変更点のdocの情報を抜き取り、docに代入します。

if (change.type === 'added')では、変更のタイプが追加されたときのみ、メッセージを追加するようにします。

今回は変更も削除もしないので、これだけです。

これでリアルタイムで反映されているかどうか見てみます。

きちんとリアルタイムで更新されていますね。

次は時系列順にしていきたいと思います。

メッセージを時系列順にする

メッセージをSlackのように時系列順にしていきます。

new Date()によって現在の時間を取得することができます。

さらに、getTimeメソッドを使い、取得した時間を数値に変換していきます。

そして、これをcreatedAtに作成日時を保存しておきます。

こんな感じです。

<script>
import { db } from '~/plugins/firebase'
export default {
  data() {
    return {
      text: null,
    }
  },
  methods: {
    addMessage(event) {
      if (this.enterJapaneseConversion(event)) {
        return
      }
      const channelId = this.$route.params.id
      db.collection('channels')
        .doc(channelId)
        .collection('messages')
        .add({ text: this.text, createdAt: new Date().getTime() })
        .then(() => {
          this.text = null
        })
    },
    enterJapaneseConversion(event) {
      const codeForConversion = 229
      return event.keyCode === codeForConversion
    },
  },
}
</script>

これで作成日時が数値で保存されるようになりました。

そしたらorderByをを使って時系列順にします。

  mounted() {
    const channelId = this.$route.params.id
    db.collection('channels')
      .doc(channelId)
      .collection('messages')
      .orderBy('createdAt')
      .onSnapshot((snapshot) => {
        snapshot.docChanges().forEach((change) => {
          const doc = change.doc
          if (change.type === 'added') {
            this.messages.push({ id: doc.id, ...doc.data() })
          }
        })
      })
  },
}
</script>

これで表示する順番が時系列順になりました。

これでSlackクローンのチャット機能は完了です。

まとめ

次はGoogleのログイン機能の実装とログインモーダルの作成をやっていきたいと思います。

徐々にSlackっぽくなってきましたね。

この調子で次回もやっていきます。

最後まで読んでいただきありがとうございます。

-PROGRAMMING

Copyright © Iseblog ,@2020 All Rights Reserved.