사용자가 투표에 참여한 게시글의 postId를 사용자의 정보가 저장된 컬렉션 문서에 객체 형태로 저장하고 싶은데
어떤 방식으로 코드를 작성해야 할지 고민이 되어 여러 시도를 해보았습니다.
저장하고 싶은 형태
join_posts = [ {postId: 'asdfs'}, {postId: 'qwert'}, {postId: 'zxcvb'}, .... ]
노란색으로 강조한 부분이 해당 문서의 id를 의미하고 저희는 id값을 postId 라는 변수로 지정했습니다.
일단 현재 사용자를 user 변수로 설정한 후 회원들의 정보가 저장된 users 컬렉션의 문서 중 uid 필드가 현재 사용자의 uid와 같은 문서의 데이터를 가져옵니다.
(firestore의 users 컬렉션에는 각 회원마다 하나의 문서에 저장되어 있고 이 문서에는 회원의 닉네임, uid, 관심주제가 저장되어 있습니다.)
지금부터 작성하는 시도해본 코드는 전부 const userDoc = querySnapshot.docs[0]; 의 하단에 작성됩니다.
첫 번째 시도
updateDoc() 을 사용하여 해당 문서에 postId 라는 키값을 가진 join_posts 를 업데이트하는 방법
if (userDoc) {
// users collection중 현재 로그인한 유저의 userDoc.id값과 일치한 문서를 찾아 업데이트함
await updateDoc(doc(db, 'users', userDoc.id), {
join_posts: { postId },
});
}
이 방법은 투표에 참여했을 때 해당 게시글의 postId 값을 firestore 문서에 잘 저장했지만, 투표에 참여한 게시글의 postId가 전부 저장되는 것이 아니라 가장 최근에 투표한 글의 postId 값 하나만 계속 업데이트되며 저장된다는 문제점이 있었습니다.
두 번째 시도
새로운 배열을 생성해서 이미 저장되어 있던 값을 복사한 다음 새로 투표에 참여한 글의 postId를 저장하고, 이 배열을 join_posts 필드 값으로 업데이트 하는 방식
if (userDoc) {
// users 문서에 join_posts 필드가 있다면 그 값을 가져오고 없다면 빈 배열 생성
const existingJoinPosts = userDoc.data().join_posts || [];
// postId가 join_posts 배열에 있는지 확인
if (!existingJoinPosts.some((joinPost) => joinPost.postId === postId)) {
const updatedJoinPosts = [...existingJoinPosts, { postId }];
await updateDoc(doc(db, 'users', userDoc.id), {
join_posts: updatedJoinPosts,
});
}
}
이 방법은 처음에 투표에 참여한 글의 postId 값 하나만 저장이 되고, 다른 게시글의 투표에 참여해도 해당 postId 는 업데이트되지 않는 문제가 있었습니다.
<br />
3. 마지막 시도
**arrayUnion() 을 사용하여 기존에 투표에 참여한 글의 postId 를 유지하며 새로 투표에 참여한 글의 postId를 join_posts 필드에 추가하는 방식**
```javascript
if (userDoc) {
await updateDoc(doc(db, 'users', userDoc.id), {
join_posts: arrayUnion({ postId }),
});
}
다른 방식을 찾아보던 중 firestore에서 배열 필드를 업데이트(배열에 없는 요소만 추가) 해주는 arrayUnion() 함수를 제공한다는 것을 알게 되었습니다.
이렇게 코드를 수정하고 나니
join_posts 필드가 제대로 업데이트 되며 원하는 형태로 postId 값들이 저장된 것을 확인할 수 있었습니다.
참고
결과적으로 파일에 import 할 것들
import { db, auth } from '../firebase-config'; // 파이어베이스 사용에 필요한 것들을 초기화해둔 파일
import {
arrayUnion,
updateDoc,
doc,
getDoc,
getDocs,
collection,
query,
where,
} from 'firebase/firestore'; // 파이어베이스와 파이어스토에서 제공하는 함수들
사용자가 투표에 참여한 게시글의 postId를 사용자의 정보가 저장된 컬렉션 문서에 객체 형태로 저장하고 싶은데 어떤 방식으로 코드를 작성해야 할지 고민이 되어 여러 시도를 해보았습니다.
일단 현재 사용자를 user 변수로 설정한 후 회원들의 정보가 저장된 users 컬렉션의 문서 중 uid 필드가 현재 사용자의 uid와 같은 문서의 데이터를 가져옵니다. (firestore의 users 컬렉션에는 각 회원마다 하나의 문서에 저장되어 있고 이 문서에는 회원의 닉네임, uid, 관심주제가 저장되어 있습니다.)
지금부터 작성하는 시도해본 코드는 전부
const userDoc = querySnapshot.docs[0];
의 하단에 작성됩니다.이 방법은 투표에 참여했을 때 해당 게시글의 postId 값을 firestore 문서에 잘 저장했지만, 투표에 참여한 게시글의 postId가 전부 저장되는 것이 아니라 가장 최근에 투표한 글의 postId 값 하나만 계속 업데이트되며 저장된다는 문제점이 있었습니다.
두 번째 시도 새로운 배열을 생성해서 이미 저장되어 있던 값을 복사한 다음 새로 투표에 참여한 글의 postId를 저장하고, 이 배열을 join_posts 필드 값으로 업데이트 하는 방식
다른 방식을 찾아보던 중 firestore에서 배열 필드를 업데이트(배열에 없는 요소만 추가) 해주는 arrayUnion() 함수를 제공한다는 것을 알게 되었습니다. 이렇게 코드를 수정하고 나니
join_posts 필드가 제대로 업데이트 되며 원하는 형태로 postId 값들이 저장된 것을 확인할 수 있었습니다.
결과적으로 파일에 import 할 것들