質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

Q&A

解決済

1回答

739閲覧

【Vue x RealtimeDatabase】Firestoreにてデータを保存しているユーザー情報を取得して名前とアンコンを表示したいです。

TMTN

総合スコア53

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

0グッド

0クリップ

投稿2021/05/13 11:57

編集2021/05/27 10:20

#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(); },

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TMTN

2021/05/14 02:07

1T2R3M4様 ご指摘ありがとうございます。 対応済です。大変申し訳ございませんでした。
guest

回答1

0

自己解決

以下コードでthis.userDatas(配列)に入っている値uesr.uidとidが一致したものを表示させて実装することができました。

<div class="otherimage flex"> <router-link :to="`/mypage/${returnUserData(userid).uid}`"> <img :src=" returnUserData(userid) ? returnUserData(userid).uploadedImage.fileUrl : preview " width="50" height="50" /> <div class="othername flex"> {{ returnUserData(userid) ? returnUserData(userid).name : "NO NAME" }} </div> </router-link> </div>
export default { components: { Nl2br }, data() { return { userIds: [], userDatas: [], preview: require("../assets/デフォルト画像.jpg"), }; }, childAdded(snap) { const message = JSON.parse(JSON.stringify(snap.val())); if (!this.userIds.includes(String(message.userid))) { this.userIds.push(String(message.userid)); let self = this; firebase .firestore() .collection("users") .doc(message.userid) .get() .then((snapshot) => { self.userDatas.push(snapshot.data()); }); } returnUserData(id) { const userData = this.userDatas.find((user) => user.uid === id); return userData; },

投稿2021/06/01 23:38

TMTN

総合スコア53

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問