Vue로 PWA 개발 - 그랜파 개발자
구독 기능은 다른 회원의 마이로그를 구독하고자 하는 것이고, 언제든 구독과 해지를 자유롭게 하고 싶습니다.
ChatGPT가 제시한 구독 코드를 봤을 때 구독 컬렉션에 userId, postId, authorId, 생성시간을 저장함으로써 구독 여부를 확인할 수 있습니다. 우리의 목적은 다른 회원의 마이로그를 구독하는 것이므로 posrId는 불필요합니다. 또한 구독 해지에 대한 내용이 없으므로 구독 해지 기능이 포함되는 구독 기능을 구현해 봅시다.
To cancel a subscription to a post, we will remove the corresponding subscription entry from the Firestore subscriptions collection. Here's how you can implement the unsubscribe functionality using Vue.js and Firebase:
게시물 구독을 취소하려면 Firestore '구독' 컬렉션에서 해당 구독 항목을 삭제합니다. Vue.js 및 Firebase를 사용하여 구독 취소 기능을 구현하는 방법은 다음과 같습니다.
게시물 구독을 취소하려면 Firestore '구독' 컬렉션에서 해당 구독 항목을 삭제합니다. Vue.js 및 Firebase를 사용하여 구독 취소 기능을 구현하는 방법은 다음과 같습니다.
In your PostSubscription.vue component, you’ll need to add a function to unsubscribe a user from a post.
PostSubscription.vue 구성 요소에 사용자의 게시물 구독을 취소하는 기능을 추가해야 합니다.
<template>
<v-container>
<v-row>
<v-col cols="12" sm="8">
<v-card>
<v-card-title>{{ post.title }}</v-card-title>
<v-card-subtitle>Written by: {{ post.author }}</v-card-subtitle>
<v-card-text>{{ post.content }}</v-card-text>
<v-btn @click="toggleSubscription">
{{ isSubscribed ? "Unsubscribe" : "Subscribe to this post" }}
</v-btn>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script>
import { addDoc, collection, query, where, getDocs, deleteDoc, doc } from "firebase/firestore";
import { db, auth } from "@/firebase";
export default {
props: {
postId: {
type: String,
required: true,
},
post: {
type: Object,
required: true,
},
},
data() {
return {
isSubscribed: false, // Track if the user is subscribed
subscriptionId: null, // Track the Firestore document ID of the subscription
};
},
methods: {
// Check if the user is subscribed to this post
async checkSubscription() {
const user = auth.currentUser;
if (user) {
const subscriptionRef = collection(db, "subscriptions");
const q = query(
subscriptionRef,
where("postId", "==", this.postId),
where("userId", "==", user.uid)
);
const querySnapshot = await getDocs(q);
if (!querySnapshot.empty) {
this.isSubscribed = true;
this.subscriptionId = querySnapshot.docs[0].id; // Get the Firestore document ID for the subscription
}
}
},
// Toggle subscription: subscribe if not subscribed, unsubscribe if already subscribed
async toggleSubscription() {
if (this.isSubscribed) {
// Unsubscribe the user
await this.unsubscribeFromPost();
} else {
// Subscribe the user
await this.subscribeToPost();
}
},
// Subscribe to the post
async subscribeToPost() {
const user = auth.currentUser;
if (user) {
try {
const subscriptionRef = collection(db, "subscriptions");
const newSubscription = await addDoc(subscriptionRef, {
userId: user.uid, // Firebase user ID
postId: this.postId, // The post the user is subscribing to
authorId: this.post.authorId, // The author of the post
timestamp: new Date(), // Subscription timestamp
});
this.isSubscribed = true; // Update subscription state
this.subscriptionId = newSubscription.id; // Store the new subscription document ID
alert("Subscribed successfully!");
} catch (error) {
console.error("Error subscribing:", error);
alert("Subscription failed: " + error.message);
}
} else {
alert("You must be logged in to subscribe.");
}
},
// Unsubscribe from the post
async unsubscribeFromPost() {
const user = auth.currentUser;
if (user && this.subscriptionId) {
try {
// Reference to the subscription document in Firestore
const subscriptionDocRef = doc(db, "subscriptions", this.subscriptionId);
await deleteDoc(subscriptionDocRef); // Remove the subscription document
this.isSubscribed = false; // Update subscription state
this.subscriptionId = null; // Clear the subscription ID
alert("Unsubscribed successfully!");
} catch (error) {
console.error("Error unsubscribing:", error);
alert("Unsubscription failed: " + error.message);
}
}
},
},
mounted() {
this.checkSubscription(); // Check if the user is subscribed when the component mounts
},
};
</script>
In the subscriptions collection:
구독 컬렉션에서:
You can move this logic into a Vuex store to centralize subscription state management across your app.
이 로직을 Vuex 스토어로 이동하여 앱 전체의 구독 상태 관리를 중앙 집중화할 수 있습니다.
Here’s an example of a Vuex module for managing subscriptions:
구독 관리를 위한 Vuex 모듈의 예는 다음과 같습니다.
// store/modules/subscriptions.js
import { addDoc, collection, query, where, getDocs, deleteDoc, doc } from "firebase/firestore";
import { db, auth } from "@/firebase";
const state = {
subscriptions: [],
};
const mutations = {
SET_SUBSCRIPTIONS(state, subscriptions) {
state.subscriptions = subscriptions;
},
};
const actions = {
async fetchUserSubscriptions({ commit }) {
const user = auth.currentUser;
if (user) {
const subscriptionRef = collection(db, "subscriptions");
const q = query(subscriptionRef, where("userId", "==", user.uid));
const querySnapshot = await getDocs(q);
const subscriptions = [];
querySnapshot.forEach((doc) => {
subscriptions.push(doc.data());
});
commit("SET_SUBSCRIPTIONS", subscriptions);
}
},
async subscribeToPost({ dispatch }, { postId, authorId }) {
const user = auth.currentUser;
if (user) {
try {
const subscriptionRef = collection(db, "subscriptions");
await addDoc(subscriptionRef, {
userId: user.uid,
postId: postId,
authorId: authorId,
timestamp: new Date(),
});
dispatch("fetchUserSubscriptions");
} catch (error) {
console.error("Error subscribing:", error);
}
}
},
async unsubscribeFromPost({ dispatch }, subscriptionId) {
const user = auth.currentUser;
if (user) {
try {
const subscriptionDocRef = doc(db, "subscriptions", subscriptionId);
await deleteDoc(subscriptionDocRef);
dispatch("fetchUserSubscriptions");
} catch (error) {
console.error("Error unsubscribing:", error);
}
}
},
};
export default {
state,
mutations,
actions,
};
This functionality can easily be extended with notification features or real-time updates using Firebase Cloud Messaging or Firestore triggers.
이 기능은 알림 기능이나 Firebase 클라우드 메시징 또는 Firestore 트리거를 사용한 실시간 업데이트를 통해 쉽게 확장될 수 있습니다.