【Vue × Firebase(RDB)】チャットルーム内にいる各ユーザーのアイコンと名前を表示させる


#チャットルーム内にいる各ユーザーのアイコンと名前を表示させる

```html
<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>
```


```javascript
export default {
  components: { Nl2br },
  data() {
    return {
      user: {}, // ユーザー情報
      chat: [], // 取得したメッセージを入れる配列
      input: "", // 入力したメッセージ
      userIds: [],
      userDatas: [],
      authenticatedUser: "",
      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));
        //this.userIds（配列）にuserid含まれていていなければthis.userIds（配列）に追加

        let self = this;
        firebase
          .firestore()
          .collection("users")
          .doc(message.userid)
          .get()
          .then((snapshot) => {
            self.userDatas.push(snapshot.data());
            //メッセージを送信したuserid(ログイン中のユーザーid)の情報をuserDatasに保存
          });
      }

      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.find((user) => user.uid === id);
      return userData;
    },
```

下記にてmessage(単一)が追加される度にif文でthis.userIds（配列）にuserid含まれていていなければthis.userIds（配列）へ追加し、
Firestoreよりユーザー情報を取得し、userDatasへデータをpushしています。

※userDatasにはメッセージを送信したユーザーの情報が配列で保存されています。

```javascript
 childAdded(snap) {

      const message = JSON.parse(JSON.stringify(snap.val()));
      if (!this.userIds.includes(String(message.userid))) {
        this.userIds.push(String(message.userid));
        //this.userIds（配列）にuserid含まれていていなければthis.userIds（配列）に追加

        let self = this;
        firebase
          .firestore()
          .collection("users")
          .doc(message.userid)
          .get()
          .then((snapshot) => {
            self.userDatas.push(snapshot.data());
            //メッセージを送信したuserid(ログイン中のユーザーid)の情報をuserDatasに保存
          });
      }
```

returnUserData(id)という関数では、userDataという変数を用意してfind()を使って、上記にてthis.userDatasへ保存されたユーザー情報を参照して
uesr.uidとidが一致したものを返してます。


```javascript
  returnUserData(id) {
      const userData = this.userDatas.find((user) => user.uid === id);
      return userData;
    },
```

this.userDatasは配列の為、uidを直接渡すことは出来ない。
その為、find()の引数にuserと適当な引数を渡して、user.uidとしてthis.userDatas内のuidを取得してます。

idにつきましては、returnUserData(id)の引数でtemplate内に記述したreturnUserData(userid)を見れば確認出来ますので、つまりuseridにあたります。

このuser.uidとidが一致すればuserDataを返すコードにしております。

---

あとは、三項演算子を使用して、名前は{{ returnUserData(userid) ? returnUserData(userid).name : "NO NAME"}}
つまり、idが一致したらそのnameを表示させ、無ければ"NO NAME"と表示させる。

画像につきましても同様に img :src="returnUserData(userid) ? returnUserData(userid).uploadedImage.fileUrl : preview" width="50" height="50"
idが一致したらそのuploadedImage内にあるfileUrlを表示させ、無ければpreview（デフォルト画像）を表示させる。

```html
<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>
```

#親コンポーネントから子コンポーネントへpropsで渡す場合


###親コンポーネント(board.vue)

Firestoreのusersコレクションを参照して、userDatas(配列)にpushする。

今回は固定値ではなく変数の値を渡したいので子コンポーネントであるListに「:userDatas="userDatas"」のようにv-bindを使用して記述します。

```
<List v-for="(list, index) in paginated('paginate-log')" :index="index" :list="list" :userDatas="userDatas"  :key="list.id"/>
```

```javascript
export default {
  data() {
    return {
      userDatas: [],
    };
  },
  components: {
    Header,
    Post,
    List,
  },
  created() {
 
    firebase
      .firestore()
      .collection("users")
      .get()
      .then((snapshot) => {
        snapshot.forEach((doc) => {
          this.userDatas.push(JSON.parse(JSON.stringify(doc.data())));
        });
      });
  },
};
```

###子コンポーネント(list.vue)

```html
<img class="profile-icon" width="50" height="50" :src=" returnUserData() ? returnUserData().uploadedImage.fileUrl : preview"/>
```

```javascript
export default {
  data() {
    return {
      preview: require("../assets/デフォルト画像.jpg"),
    };
  },
  props: {
    userDatas:{
      type: Array,
      //親コンポーネント(board.vue)のuserDatasをpropsで渡している。
    }
  },

 methods: {
    returnUserData() {
      const userData = this.userDatas.find( (tmpUserData) => this.list.uid === tmpUserData.uid);
      return userData;
    },
},
```

親コンポーネントからpropsでArray(配列)でデータを受ける。

受けたデータを下記returnUserData()を使用して投稿したユーザーのuid(this.list.uid)とユーザーのuid(tmpUserData.uid)を一致させてあげる。

---

今回はpropsからデータを受けたthis.listからuidを参照しているため、returnUserData()に引数は渡しておりません。

this.userDatasは配列の為、uidを直接渡すことは出来ない。
その為、find()の引数にtmpUserDataと適当な引数を渡して、tmpUserData.uidとしてthis.userDatas内のuidを取得してます。

```
returnUserData() {
 const userData = this.userDatas.find( (tmpUserData) => this.list.uid === tmpUserData.uid);
 return userData;
    },
```

このuser.uidとidが一致すればuserDataを返すコードにしております。

---

あとは、三項演算子を使用して、画像をimg class="profile-icon" width="50" height="50" :src=" returnUserData() ? returnUserData().uploadedImage.fileUrl : preview"としてuidが一致したらそのuploadedImage内にあるfileUrlを表示させ、無ければpreview（デフォルト画像）を表示させる。

```html
<img class="profile-icon" width="50" height="50" :src=" returnUserData() ? returnUserData().uploadedImage.fileUrl : preview"/>
```