#RealtimeDatabaseにてFirestoreにてデータを保存しているユーザー情報を取得して表示したいです。
VueとFirebaseにてチャットを実装しているのですが、チャットルームにて名前とアイコンを表示させたいです。
Firestoreを使用してユーザー情報を管理しているのですが、
Realtime Databaseでそのユーザー情報を表示させたいと考えていますが、行き詰まってる状況です・・
created() { ~ 省略 ~ const currentUser = firebase.auth().currentUser; //現在ログインしているユーザーを取得 this.uid = currentUser.uid; this.userIds.forEach((id) => { firebase .firestore() .collection("users") .doc(id) .get() .then((snapshot) => { this.userDatas.push(snapshot.data()); }); }); }, methods: { scrollBottom() { this.$nextTick(() => { window.scrollTo(0, document.body.clientHeight); }); }, childAdded(snap) { const message = snap.val(); if (!this.userIds.includes(message.userid)) this.userIds.push(message.userid); this.chat.push({ key: snap.key, name: message.name, image: message.image, message: message.message, userid: message.userid, time: message.time, }); this.scrollBottom(); }, returnUserData(id) { const userData = this.userDatas.filter((user) => user.id === id); return userData; },
上記のように記載して表示させて、filterメソッドを使ってidからユーザーを取り出そうと考えていますが、
どのようにここから記述したらいいのかわからない状況です。
分かる方いらっしゃいましたらお力添えをいただきたいです。
お手数おかけしますが、よろしくおがいいたします。
html
1<template> 2 <div class="chat"> 3 <h1 class="chat-tll flex"> 4 <div class="flash neon">Chat Room</div> 5 <router-link :to="`/board/${this.uid}`" class="back-btn"> 6 <img 7 src="../assets/戻る.jpg" 8 alt="チャット終了" 9 class="back-btn-icon" 10 /> 11 </router-link> 12 </h1> 13 <!--Firebase から取得したリストを描画--> 14 <transition-group name="chat" tag="div" class="list content"> 15 <!--chatの中の{ key, name, image, message ,userid }をそれぞれ取得--> 16 <section 17 v-for="{ key, name, image, message, userid, time } in chat" 18 :key="key" 19 > 20 <div v-if="userid === user.uid" class="myitem flex"> 21 {{ userDatas }} 22 <!-- 自身 --> 23 <!--「画像」の指定--> 24 25 <!--「名前」と「メッセージ」の指定--> 26 <div class="mydetail"> 27 <div class="mytime">{{ $dayjs(time).format("hh:mm") }}</div> 28 <div @click.right.prevent="deleteMessage(key)" class="mymessage"> 29 <nl2br tag="div" :text="message" /> 30 </div> 31 </div> 32 <div class="myimage flex"> 33 <img :src="image" width="40" height="40" /> 34 <div class="myname">{{ name }}</div> 35 </div> 36 </div> 37 <div v-else class="otheritem flex"> 38 <!-- 自身ではない --> 39 <!--「画像」の指定--> 40 <div class="otherimage flex"> 41 <img :src="image" width="40" height="40" /> 42 <div class="othername">name</div> 43 </div> 44 <!--「名前」と「メッセージ」の指定--> 45 <div class="otherdetail"> 46 <div class="othermessage"> 47 <nl2br tag="div" :text="message" /> 48 </div> 49 <div class="othertime">{{ $dayjs(time).format("hh:mm") }}</div> 50 </div> 51 </div> 52 </section> 53 </transition-group> 54 55 <!-- 入力フォームの設定 --> 56 <div class="message-inner flex"> 57 <form action @submit.prevent="doSend" class="form flex"> 58 <textarea 59 v-model="input" 60 placeholder="メッセージを入力" 61 :disabled="!user.uid" 62 @keydown.enter.exact.prevent="doSend" 63 ></textarea> 64 <!-- ユーザーでなければ無効化 --> 65 <button type="submit" :disabled="!user.uid" class="send-button"> 66 <img src="../assets/電球.jpg" class="send-img" alt="送信" /> 67 </button> 68 </form> 69 </div> 70 </div> 71</template>
js
1<script> 2import firebase from "firebase"; 3import Nl2br from "vue-nl2br"; 4import Vue from "vue"; 5// 改行を <br> タグに変換するモジュール 6import dayjs from "dayjs"; 7 8dayjs.locale("ja"); 9Vue.prototype.$dayjs = dayjs; 10 11export default { 12 components: { Nl2br }, 13 data() { 14 return { 15 user: {}, // ユーザー情報 16 chat: [], // 取得したメッセージを入れる配列 17 input: "", // 入力したメッセージ 18 usersData: [], 19 profileDeta: {}, 20 userIds: [], 21 userDatas: [], 22 }; 23 }, 24 created() { 25 firebase.auth().onAuthStateChanged((user) => { 26 // ログイン状態ならuserが取得できる 27 this.user = user ? user : {}; 28 //firebase.database()で以下のデータベースの読み書きを行う。 29 const ref_message = firebase.database().ref(this.$route.params.id); 30 //[router.vue]にて「/ ~ /:id」と指定しルートがマッチした時、 31 //この動的セグメントの値は全てのコンポーネント内で this.$route.params として利用可能になる。 32 if (user) { 33 this.chat = []; 34 // limitToLast(10)で並べ替えられた「message」の最後の10個を取得。 35 // on()は、message に変更があったときのハンドラを登録 36 //child_addedは、データベースのリスト「message」を取得。 37 ref_message.limitToLast(10).on("child_added", this.childAdded); 38 } else { 39 // message に変更があったときのハンドラを解除 40 ref_message.limitToLast(10).off("child_added", this.childAdded); 41 } 42 }); 43 const currentUser = firebase.auth().currentUser; 44 //現在ログインしているユーザーを取得 45 this.uid = currentUser.uid; 46 47 this.userIds.forEach((id) => { 48 firebase 49 .firestore() 50 .collection("users") 51 .doc(id) 52 .get() 53 .then((snapshot) => { 54 this.userDatas.push(snapshot.data()); 55 }); 56 }); 57 console.log(this.userIds); 58 }, 59 methods: { 60 // スクロール位置を一番下に移動 61 scrollBottom() { 62 this.$nextTick(() => { 63 //this.$nextTickは、再描画を待つ。 64 //絶対値からbody要素の高さを取得 65 window.scrollTo(0, document.body.clientHeight); 66 }); 67 }, 68 childAdded(snap) { 69 //snapshotとは、ある時点における特定のデータベース参照にあるデータの全体像を写し取ったもの 70 //childAdded:データベースからアイテムのリストを取得する関数 71 // 受け取ったメッセージをchatに追加 72 const message = snap.val(); 73 if (!this.userIds.includes(message.userid)) 74 this.userIds.push(message.userid); 75 //イベントのときにデータベース内の「message」データを取得。 76 // データベースに新しい要素が追加されると随時呼び出される 77 this.chat.push({ 78 key: snap.key, 79 name: message.name, 80 image: message.image, 81 message: message.message, 82 userid: message.userid, 83 time: message.time, 84 }); 85 this.scrollBottom(); 86 //スクロールの一番下に追加。 87 }, 88 doSend() { 89 const time = time; 90 if (this.user.uid && this.input.length) { 91 // firebaseに書き込まれたメッセージを追加 92 firebase 93 .database() 94 .ref(this.$route.params.id) 95 .push( 96 { 97 message: this.input, 98 name: this.user.displayName, 99 image: this.user.photoURL, 100 userid: this.user.uid, 101 time: firebase.database.ServerValue.TIMESTAMP, 102 }, 103 104 () => { 105 this.input = ""; // フォームを空にする 106 } 107 ); 108 } 109 }, 110 returnUserData(id) { 111 const userData = this.userDatas.filter((user) => user.id === id); 112 return userData; 113 }, 114 deleteMessage(key) { 115 firebase 116 .database() 117 .ref(this.$route.params.id + "/" + key) 118 .remove(); 119 console.log(key); 120 this.$swal({ 121 title: "内容確認", 122 text: "メッセージを削除しますか?", 123 icon: "warning", 124 buttons: true, 125 dangerMode: true, 126 }).then((willDelete) => { 127 if (willDelete) { 128 this.$swal("メッセージを削除しました", { 129 icon: "success", 130 }); 131 this.$router.go({ 132 path: `/chat/${this.$route.params.id}`, 133 force: true, 134 }); 135 } else { 136 this.$swal("キャンセルしました。"); 137 } 138 }); 139 }, 140 }, 141}; 142</script>
#追記1
const currentUser = firebase.auth().currentUser; //現在ログインしているユーザーを取得 this.uid = currentUser.uid; this.userIds.forEach((id) => { firebase .firestore() .collection("users") .doc(id) .get() .then((snapshot) => { this.userDatas.push(snapshot.data()); }); }); console.log(this.userIds); },
上記、現状this.userIds.forEach((id)の部分でforEachが機能していない状況です。
this.userIdsの値は画像にあるようにobserverでデータは取得できていますが、配列でない為、
データがforEachにわたっていないように見受けられます。
※ this.userDatasの値を確認しようとしてもコンソール自体機能しなかった為。
引き続き分かる方いらっしゃいましたらお力添えを頂きたいです。
宜しくお願い致します。
#追記2
長期間回答が得られない為、以下サイトにも掲載させて頂いております。
【Vue x RealtimeDatabase】Firestoreにてデータを保存しているユーザー情報を取得して名前とアンコンを表示したいです。
#追記3
this.userIds.forEach((id) => { firebase .firestore() .collection("users") .doc(id) .get() .then((snapshot) => { this.userDatas.push(snapshot.data()); }); });
上記forEachがオブサーバー型になっており、機能していなかったため、下記の段階でjson型に変えてみました。
しかし、if文に入ったthis.userIdsをコンソールを確認しましたが、再びオブサーバー型になってしまいます。
message.userIdのデータ型がstringになるようにしてから、this.userIdsにpushしたいのですが、
stringにして渡すやり方をお伺いしたいです。
childAdded(snap) { const message = JSON.parse(JSON.stringify(snap.val())); if (!this.userIds.includes(String(message.userid))) this.userIds.push(String(message.userid)); console.log(this.userIds); this.chat.push({ key: snap.key, name: message.name, image: message.image, message: message.message, userid: message.userid, time: message.time, }); this.scrollBottom(); },
回答1件
あなたの回答
tips
プレビュー