Skip to content

Commit

Permalink
feat: fetchPosts API 추가 (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
nakyeonko3 committed Sep 2, 2024
1 parent 47845d6 commit 183237b
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 1 deletion.
1 change: 1 addition & 0 deletions .github/.gitmessage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@
# 제목과 본문을 한 줄 띄워 분리하기
# 본문은 "어떻게" 보다 "무엇을", "왜"를 설명한다.
# 본문에 여러줄의 메시지를 작성할 땐 "-"로 구분
# git config commit.template .github/.gitmessage.txt
# ------------------
195 changes: 195 additions & 0 deletions src/api/fetchPosts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
import {
collection,
doc,
getDoc,
getDocs,
query,
where,
orderBy,
limit,
startAfter,
} from 'firebase/firestore';

import { db } from '@/api/firebaseApp';
import { PostModel } from '@/types/post';

const postsCollection = collection(db, 'posts');

export async function getPostsFilterdLikes({
userId,
count = 10,
lastPostId,
}: {
userId: string;
count?: number;
lastPostId?: string;
}): Promise<PostModel[]> {
let q = query(
postsCollection,
where('likes', 'array-contains', userId),
orderBy('createdAt', 'desc'),
limit(count),
);

if (lastPostId) {
const lastPostDoc = await getDoc(doc(postsCollection, lastPostId));
if (lastPostDoc.exists()) {
q = query(q, startAfter(lastPostDoc));
}
}

const querySnapshot = await getDocs(q);
return querySnapshot.docs.map((doc) => ({ postId: doc.id, ...doc.data() }) as PostModel);
}

export async function getPostsByUserId({
userId,
count = 10,
lastPostId,
}: {
userId: string;
count?: number;
lastPostId?: string;
}): Promise<PostModel[]> {
let q = query(
postsCollection,
where('userId', '==', userId),
orderBy('createdAt', 'desc'),
limit(count),
);

if (lastPostId) {
const lastPostDoc = await getDoc(doc(postsCollection, lastPostId));
if (lastPostDoc.exists()) {
q = query(q, startAfter(lastPostDoc));
}
}

const querySnapshot = await getDocs(q);
return querySnapshot.docs.map((doc) => ({ postId: doc.id, ...doc.data() }) as PostModel);
}

export async function getPostsByFollowingUsers({
userId,
count = 100,
lastPostId,
}: {
userId: string;
count?: number;
lastPostId?: string;
}): Promise<PostModel[]> {
const userDoc = await getDoc(doc(db, 'users', userId));
if (!userDoc.exists()) {
console.warn('User not found');
return [];
}

const followingUserIds = userDoc.data().following;
if (!followingUserIds || followingUserIds.length === 0) {
console.warn('No following users');
return [];
}

let q = query(
postsCollection,
orderBy('createdAt', 'desc'),
where('userId', 'in', followingUserIds),
limit(count),
);

if (lastPostId) {
const lastPostDoc = await getDoc(doc(postsCollection, lastPostId));
if (lastPostDoc.exists()) {
q = query(q, startAfter(lastPostDoc));
}
}

const querySnapshot = await getDocs(q);
return querySnapshot.docs.map((doc) => ({ postId: doc.id, ...doc.data() }) as PostModel);
}

export async function getPosts({
count = 10,
lastPostId,
}: {
count?: number;
lastPostId?: string;
}): Promise<PostModel[]> {
let q = query(postsCollection, orderBy('createdAt', 'desc'), limit(count));

if (lastPostId) {
const lastPostDoc = await getDoc(doc(postsCollection, lastPostId));
if (lastPostDoc.exists()) {
q = query(q, startAfter(lastPostDoc));
}
}

const querySnapshot = await getDocs(q);
return querySnapshot.docs.map((doc) => ({ postId: doc.id, ...doc.data() }) as PostModel);
}

export async function getPostsTimelinesSorted({
userId,
count = 20,
lastPostId,
}: {
userId: string;
count?: number;
lastPostId?: string;
}): Promise<PostModel[]> {
const userDoc = await getDoc(doc(db, 'users', userId));
if (!userDoc.exists()) {
console.warn('User not found');
return [];
}

const followingUserIds = userDoc.data()?.following || [];
if (!followingUserIds || followingUserIds.length === 0) {
console.warn('No following users');
return [];
}

let followingPostsQuery = query(
postsCollection,
where('userId', 'in', [userId, ...followingUserIds]),
orderBy('createdAt', 'desc'),
limit(count),
);

if (lastPostId) {
const lastPostDoc = await getDoc(doc(postsCollection, lastPostId));
if (lastPostDoc.exists()) {
followingPostsQuery = query(followingPostsQuery, startAfter(lastPostDoc));
}
}

const followingPostsSnapshot = await getDocs(followingPostsQuery);
const followingPosts = followingPostsSnapshot.docs.map(
(doc) => ({ postId: doc.id, ...doc.data() }) as PostModel,
);

if (followingPosts.length < count) {
const remainingCount = count - followingPosts.length;
const lastFollowingPost = followingPosts[followingPosts.length - 1];

let otherPostsQuery = query(
postsCollection,
where('userId', 'not-in', [userId, ...followingUserIds]),
orderBy('createdAt', 'desc'),
limit(remainingCount),
);

if (lastFollowingPost) {
otherPostsQuery = query(otherPostsQuery, startAfter(lastFollowingPost.createdAt));
}

const otherPostsSnapshot = await getDocs(otherPostsQuery);
const otherPosts = otherPostsSnapshot.docs.map(
(doc) => ({ postId: doc.id, ...doc.data() }) as PostModel,
);

return [...followingPosts, ...otherPosts];
}

return followingPosts;
}
23 changes: 23 additions & 0 deletions src/api/fetchUsers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { collection, doc, getDoc, updateDoc } from 'firebase/firestore';

import { db } from '@/api/firebaseApp';
import { UserModel } from '@/types/user';

const usersCollection = collection(db, 'users');

export async function getUserInfoByUserId({ userId }: { userId: string }): Promise<UserModel> {
const userDoc = doc(usersCollection, userId);
const userDocSnapshot = await getDoc(userDoc);
return { userId: userDocSnapshot.id, ...userDocSnapshot.data() } as UserModel;
}

export async function updateUserInfoByUserId({
userId,
displayName,
email,
photoURL,
}: UserModel): Promise<UserModel> {
const userDoc = doc(usersCollection, userId);
await updateDoc(userDoc, { displayName, photoURL, email });
return { userId, displayName, email, photoURL };
}
25 changes: 24 additions & 1 deletion src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
import { useState, useEffect } from 'react';

import { getPostsFilterdLikes } from '@/api/fetchPosts';
import LogoHeader from '@/components/layout/header/LogoHeader';
import { PostModel } from '@/types/post';

const HomePage = () => {
const [posts, setPosts] = useState<PostModel[]>([]);

useEffect(() => {
const fetchPosts = async () => {
const timelinePosts = await getPostsFilterdLikes({
userId: '43XSFCaxWQX0dVoGKWtbMoI6SyD2',
count: 10,
lastPostId: undefined,
});
setPosts(timelinePosts);
};

fetchPosts();
}, []);

return (
<>
<LogoHeader />
<div>HomePage</div>
{posts.map((post) => (
<div key={post.postId}>
<p>{post.content}</p>
</div>
))}
</>
);
};
Expand Down

0 comments on commit 183237b

Please sign in to comment.