블로그 독자
나를 구독하는 사람들은 누구일까요?
나를 구독하는 사람들을 독자라고 합시다.
나의 독자들의 목록을 보여주고,
목록에서 독자를 선택하면 .그 독자의 블로그를 볼 수 있습니다.

블로그 독자 요구 분석
내가 구독하는 저자는 subscriptions 컬렉션에서 authorId입니다.
나를 구독하는 독자는 subscriptions 컬렉션에서 나를 authorId로 저장한 사용자 입니다.
독자들의 목록을 구하기 위하여 subscriptions 컬렉션에 나를 authorId로 저장한 userId들을 구해서
이들의 이메일과 이름을 목록으로 보여줍니다.
목록에서 독자를 선택하면 그 독자의 블로그로 이동할 수 있습니다.
ReadersView 컴포넌트의 script

store의 post 모듈 - readers
// src/store/modules/post.js
import { v4 as uuidv4 } from 'uuid';
import { db, collection, getDocs, getDoc, setDoc, doc,
addDoc, updateDoc, deleteDoc, query, where, orderBy,
increment, arrayUnion } from "@/firebase";
const state = {
. . .
readers: [], // 독자들
};
const mutations = {
. . .
setReaders(state, readers) { // 독자들
state.readers = readers;
},
};
const actions = {
. . .
// -- 독자 ------
// 1. subscriptions 컬렉션의 문서에서 authorId가 나의 id인 userId 배열을 구한다.
// 2. userId의 배열에 포함된 userId를 가진 모든 회원의 정보를 얻어 목록으로 나타낸다.
async fetchReaders({ commit, rootState }, userId) {
commit('setLoading', true);
commit("setReaders", null);
console.log(userId);
// 구독 목록
const userIds = [];
const q = query(collection(db, "subscriptions"), where("authorId", "==", userId));
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
userIds.push(doc.data().userId);
});
if(userIds.length> 0)
{
let readers = []; //독자들
for (const userId of userIds) {
const author = rootState.auth.profiles.find(profile => profile.userId == userId);
if (author) {
readers.push(author);
} else {
alert(`No such user with ID: ${userId}`);
}
}
// 구독 마이로그 목록을 상태에 저장
commit("setReaders", readers);
}
commit('setLoading', false);
},
};
const getters = {
};
export default {
namespaced: true,
state,
mutations,
actions,
getters
};
ReadersView.vue
<!-- src/views/ReadersView.vue -->
<template>
<v-container>
<v-card>
<v-card-title>독자들</v-card-title>
<v-list v-if="readers && readers.length > 0">
<v-list-item v-for="reader in readers" :key="reader.id" @click="goToBlog(reader.userId)">
<v-list-item-content>
<v-list-item-title style="font-size:1em">{{ reader.name }}</v-list-item-title>
<v-list-item-subtitle>{{ reader.email }}</v-list-item-subtitle>
</v-list-item-content>
</v-list-item>
</v-list>
</v-card>
<div class="text-center">
<v-progress-circular v-if="loading" indeterminate></v-progress-circular>
</div>
</v-container>
</template>
<script>
import { mapActions, mapState } from "vuex";
export default {
data() {
return {
};
},
async created() {
const userId = this.profile.userId;
this.fetchReaders(userId);
},
computed: {
...mapState('auth',['user', 'profile']),
...mapState('post',['readers', 'loading']),
},
methods: {
...mapActions('post', ['fetchReaders']),
goToBlog(userId) {
this.$router.push({ name: 'Blog', params: { userId } });
},
}
};
</script>
'토이 프로젝트 - Vue, Firebase로 서버리스 PWA 개발' 카테고리의 다른 글
29. Vue와 Firebase로 사이드 프로젝트 PWA myBlog 개발 - 푸시 알림 서비스 (0) | 2025.03.07 |
---|---|
28. 사이드 프로젝트 푸시 알림 Firebase Cloud Messaging (FCM)이란? (1) | 2025.03.06 |
26. 사이드 프로젝트 PWA myBlog 개발 - 블로그 구독 (0) | 2025.03.02 |
25. Vue와 Firebase 서버리스 PWA myBlog 개발 - 블로그 검색 (0) | 2025.03.02 |
24. Vue와 Firebase 서버리스 PWA myBlog 개발 - 블로그 보기 (0) | 2025.03.01 |