前置き
前回の続きです🙋♀️
【Nuxt.js】開発ブログ:firebaseでチャットアプリ①
ログイン機能をつけたり
ちょっとした
見た目の調整をしていきます♪
今回もあまり丁寧な解説はありません。
コードも綺麗ではないですが
参考になればと思います🎈🧸
参考:
スマホアプリ開発を加速する,Firebaseを使ってみよう 第10回[最終回] Firebaseの実践的なテクニックを使いこなそう
Firebase サーバ時間の取得
見た目の調整
前回はメッセージを配列で
横並びに表示しただけだったので
見た目の調整をしていきます✨👀
自分のメッセージがどれか
分かれば良いので
デザインは適当です🐥
変数の命名も分かりにくかったので
firebaseから取ってくるデータはposts
という変数にしました💡
自分(yossy)の投稿した物は
クラスバインディングでme
というクラスをつけています🧸
基本的に
スタイリングをする要素は
全てクラス名をつけますが、
一旦タグで指定してます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
<template> <div class="page"> <ul> <li v-for="post in posts" :key="post.id" :class="{ me: post.name === 'yossy'}" > <div> {{ post.name }} | {{ post.message }} </div> </li> </ul> <form @submit.prevent="submit"> <label> <span> 名前: </span> <input type="text" v-model="user.name" > </label> <label> <span> message: </span> <input v-model="user.message" > </label> <button type="submit" > Submit </button> </form> </div> </template> <script> import axios from 'axios' import firebase from '@/plugins/firebase' export default { created() { return axios .get('https://sample-6a560.firebaseio.com/message.json') .then((res) => { const postArray = [] for (const key in res.data) { let allKey = res.data[key] postArray.push(allKey) } this.posts = postArray console.log(this.posts) }) }, data () { return { user: { name: "", message: "", }, posts: "", } }, methods: { submit (postData) { let Ref = firebase.database().ref().child('message') Ref.push({ name: this.user.name, message: this.user.message }) .then(response => { this.getData () }) }, getData () { return axios .get('https://sample-6a560.firebaseio.com/message.json') .then((res) => { const postArray = [] for (const key in res.data) { let allKey = res.data[key] postArray.push(allKey) console.log(allKey) } this.posts = postArray }) }, }, } </script> <style lang="scss" scoped> .page { padding: 20px; > ul { > li { display: flex; margin-bottom: 10px; &.me { justify-content: flex-end; > div { background-color: pink; } } } } > form { margin-top: 20px; background-color: rgba(255, 192,203, 0.1); > label, button { display: block; > input { border: 1px solid pink; } } } } </style> |
ログイン機能の実装
ベース作り
こちらもfirebaseで実装しています🍀
ログインフォームを追加して
Authenticationに予め登録した
自分のメールアドレスにログインします。
ログインしたメアドなら
メッセージにme
クラスをつけます。
今の段階だと
どのアカウントによる
メッセージか判別がつかないため
全てのメッセージにme
クラスがついています💡
⬇️ログインについては
こちらを参考にしてください🌟
【Nuxt.js】firebase基礎編(Auth版):メールアドレスログインをできるようにしよう
ログイン情報保持のためにVuex
にしたいところですが
一旦index.vueで
全て行っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
<template> <div class="page"> <form class="form" @submit.prevent > <label class="label"> <span class="label"> email </span> <input class="input" type="text" v-model="email" > </label> <label class="label"> <span class="label"> password </span> <input class="input" type="password" v-model="password" > </label> <button class="button" type="submit" @click="login" > Login </button> </form> <ul> <li v-for="post in posts" :key="post.id" :class="{ me: user.email === 'Authenticationに登録した自分のメールアドレス'}" > <div> {{ post.name }} | {{ post.message }} </div> </li> </ul> <form @submit.prevent> <label> <span> 名前: </span> <input type="text" v-model="user.name" > </label> <label> <span> message: </span> <input v-model="user.message" > </label> <button type="submit" @click="submit" > Submit </button> </form> </div> </template> <script> import axios from 'axios' import firebase from '@/plugins/firebase' export default { created() { return axios .get('https://sample-6a560.firebaseio.com/message.json') .then((res) => { const postArray = [] for (const key in res.data) { let allKey = res.data[key] postArray.push(allKey) } this.posts = postArray // console.log(this.posts) }) }, data () { return { email: '', password: '', user: { email: '', name: "", message: "", }, posts: "", } }, methods: { submit (postData) { let Ref = firebase.database().ref().child('message') Ref.push({ name: this.user.name, message: this.user.message }) .then(response => { this.getData () }) }, getData () { return axios .get('https://sample-6a560.firebaseio.com/message.json') .then((res) => { const postArray = [] for (const key in res.data) { let allKey = res.data[key] postArray.push(allKey) // console.log(allKey) } this.posts = postArray }) }, login() { firebase.auth().signInWithEmailAndPassword(this.email, this.password) .then(data => { console.log(data.user.email) this.user.email = data.user.email }).catch((error) => { console.log(error) }); }, }, } </script> <style lang="scss" scoped> .page { padding: 20px; > ul { > li { display: flex; margin-bottom: 10px; &.me { justify-content: flex-end; > div { background-color: pink; } } } } > form { margin-top: 20px; background-color: rgba(255, 192,203, 0.1); > label, button { display: block; > input { // border: 1px solid #0090A8; border: 1px solid pink; } } } } </style> |
どのアカウントのメッセージか判別する
ログインした時に取得したメアドをuserId
というプロパティでsubmit
📤
送信したuserId
と
現在ログイン中の
メールアドレス(user.email
)が
一致すればOKですね⭕️🙆♀️
ログインしていない状態で
guestとして投稿した後、
ログインしてから再投稿してチェック✅
ゲストが複数いる場合でも
1人として扱われてしまいますが、
ログインして使う物なので
そこは深く追求しません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
<template> <div class="page"> <form class="form" @submit.prevent > <label class="label"> <span class="label"> email </span> <input class="input" type="text" v-model="email" > </label> <label class="label"> <span class="label"> password </span> <input class="input" type="password" v-model="password" > </label> <button class="button" type="submit" @click="login" > Login </button> </form> <ul> <li v-for="post in posts" :key="post.id" :class="{ me: user.email === post.userId}" > <div> {{ post.name }} | {{ post.message }} </div> </li> </ul> <form @submit.prevent> <label> <span> 名前: </span> <input type="text" v-model="user.name" > </label> <label> <span> message: </span> <input v-model="user.message" > </label> <button type="submit" @click="submit" > Submit </button> </form> </div> </template> <script> import axios from 'axios' import firebase from '@/plugins/firebase' export default { created() { return axios .get('https://sample-6a560.firebaseio.com/message.json') .then((res) => { const postArray = [] for (const key in res.data) { let allKey = res.data[key] postArray.push(allKey) } this.posts = postArray // console.log(this.posts) }) }, data () { return { email: '', password: '', user: { email: '', name: "", message: "", }, posts: "", } }, methods: { submit (postData) { let Ref = firebase.database().ref().child('message') Ref.push({ name: this.user.name, message: this.user.message, userId: this.user.email }) .then(response => { this.getData () }) }, getData () { return axios .get('https://sample-6a560.firebaseio.com/message.json') .then((res) => { const postArray = [] for (const key in res.data) { let allKey = res.data[key] postArray.push(allKey) // console.log(allKey) } this.posts = postArray }) }, login() { firebase.auth().signInWithEmailAndPassword(this.email, this.password) .then(data => { console.log(data.user.email) this.user.email = data.user.email }).catch((error) => { console.log(error) }); }, }, } </script> <style lang="scss" scoped> .page { padding: 20px; > ul { > li { display: flex; margin-bottom: 10px; &.me { justify-content: flex-end; > div { background-color: pink; } } } } > form { margin-top: 20px; background-color: rgba(255, 192,203, 0.1); > label, button { display: block; > input { // border: 1px solid #0090A8; border: 1px solid pink; } } } } </style> |
タイムスタンプの追加
公式: TIMESTAMP
送信時に時刻保存
firebaseにpush
した際に
時刻を保存してくれる仕組みがあります。
保存形式はUnixのミリ秒みたいですね。
ということでmethods
のsubmit
に
該当コードを追加✍️
1 2 3 4 5 6 7 8 9 10 11 |
methods: { submit (postData) { let Ref = firebase.database().ref().child('message') // 追記 let stamp = firebase.database.ServerValue.TIMESTAMP Ref.push({ name: this.user.name, message: this.user.message, userId: this.user.email, time: stamp }) .then(response => { this.getData () }) }, }, |
表示はdayjs
⬇️インストールや
基本的な使い方はこちら
【Nuxt.js】dayjs導入編:リアルタイムな日時を表示してみよう
Month,Dayと
Hour, minutesで表示。
1 2 3 4 5 6 7 8 9 10 11 |
<ul> <li v-for="post in posts" :key="post.id" :class="{ me: user.email === post.userId}" > <div> {{ post.name }} | {{ post.message }} | {{ $dayjs(post.time).format('MM-DD HH:mm') }} </div> </li> </ul> |
ここまでの全体のコードはこちら。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
<template> <div class="page"> <form class="form" @submit.prevent > <label class="label"> <span class="label"> email </span> <input class="input" type="text" v-model="email" > </label> <label class="label"> <span class="label"> password </span> <input class="input" type="password" v-model="password" > </label> <button class="button" type="submit" @click="login" > Login </button> </form> <ul> <li v-for="post in posts" :key="post.id" :class="{ me: user.email === post.userId}" > <div> {{ post.name }} | {{ post.message }} | {{ $dayjs(post.time).format('MM-DD HH:mm') }} </div> </li> </ul> <form @submit.prevent> <label> <span> 名前: </span> <input type="text" v-model="user.name" > </label> <label> <span> message: </span> <input v-model="user.message" > </label> <button type="submit" @click="submit" > Submit </button> </form> </div> </template> <script> import axios from 'axios' import firebase from '@/plugins/firebase' export default { created() { return axios .get('https://sample-6a560.firebaseio.com/message.json') .then((res) => { const postArray = [] for (const key in res.data) { let allKey = res.data[key] postArray.push(allKey) } this.posts = postArray // console.log(this.posts) }) }, data () { return { email: '', password: '', user: { email: '', name: "", message: "", }, posts: "", } }, methods: { submit (postData) { let Ref = firebase.database().ref().child('message') let stamp = firebase.database.ServerValue.TIMESTAMP Ref.push({ name: this.user.name, message: this.user.message, userId: this.user.email, time: stamp }) .then(response => { this.getData () }) }, getData () { return axios .get('https://sample-6a560.firebaseio.com/message.json') .then((res) => { const postArray = [] for (const key in res.data) { let allKey = res.data[key] postArray.push(allKey) // console.log(allKey) } this.posts = postArray }) }, login() { firebase.auth().signInWithEmailAndPassword(this.email, this.password) .then(data => { console.log(data.user.email) this.user.email = data.user.email }).catch((error) => { console.log(error) }); }, }, } </script> <style lang="scss" scoped> .page { padding: 20px; > ul { margin-top: 100px; background-color: #f8f8f8; padding: 24px 8px; > li { display: flex; margin-bottom: 10px; &.me { justify-content: flex-end; > div { background-color: pink; } } } } > form { margin-top: 20px; background-color: rgba(255, 192,203, 0.1); > label, button { display: block; > input { // border: 1px solid #0090A8; border: 1px solid pink; } } } } </style> |
まとめ
それらしくなってきました💫
次はstorageを使用して
スタンプ機能を入れたり、
Vuexに移行していきます。
見た目もチャット感を出したいです🤔💭
すっかり忘れていましたがsubmit
した後の
inputの中のテキストが邪魔なので
消しておきます😂笑
1 2 3 4 5 6 7 8 9 10 |
submit (postData) { let Ref = firebase.database().ref().child('message') let stamp = firebase.database.ServerValue.TIMESTAMP Ref.push({ name: this.user.name, message: this.user.message, userId: this.user.email, time: stamp }) .then(response => { this.getData () this.user.name = '' this.user.message = '' }) }, |
構成など何も考えず
とりあえず実装してきましたが、
今までの記事の組み合わせで
全て成り立っているので
意外とやりやすかったです😁💕