오류기록) FirebaseError: No document to update(firestore에 있는 문서를 수정,삭제할 때)

BakJiYeon·2022년 1월 26일
0

오류

GET https://firestore.googleapis.com/google.firestore.v1.Firestore/Write/channel?database=projects~ (생략) net::ERR_FAILED 200

Uncaught (in promise) FirebaseError: No document to update: projects/nwitter-7c89a/databases/(default)/documents/postings/undefined

작성된 글을 수정, 삭제하는 버튼을 누르면 위의 오류가 나타난다.
내가 수정하려는 문서가 없다고 한다.

Check

  • 진짜 없거나 ✔
    --> 있다. 데이터베이스에서 확인된다.
  • ref설정을 잘못했거나
    --> firebase 문서에서 updateDoc을 찾아보니 아래와 같다.

updateDoc(reference, data)

작성한 코드 확인

await updateDoc(doc(firestore, "postings", `${posting.id}`), {
      text: postingEditing,
    });

Check

  • reference : doc(firestore, "postings", ${posting.id}
    a) doc()의 파라미터 ✔
    b) 변수 posting
    --> type:string ✔
    --> * property를 확인
  • 2) data ✔

-* property를 확인
posting은 아래와 같은 형태이다.

[{
	text: "Hi, there!",
    	creatorId: abcdefg,
        createdAt: 123456789,
},
{
	text: "Snowing Outside!",
    	creatorId: abcdefg,
        createdAt: 144222333,
},
]

문제는 각 Object에 value가 id인 property가 없어서 발생했다.
id는 아래 코드로 추가하고 있다. 여기에서 작동이 안 된 듯하다.

코드A

const getPostings = async () => {
    const q = query(collection(firestore, "postings"));
    onSnapshot(q, (querySnapshot) => {
      const docData = querySnapshot.docs.map((doc) => {
        return {
          id: doc.id,
          ...doc.data(),
        };
      });
      setPostings(docData);
    });

위의 함수가 실행 중일 때는 postings에 id가 잘 담긴다.
그런데 함수가 일을 마친 후 다시 렌더링되면, postings에서 id가 사라진다.

그렇다면..

그 후에 다른 기능이 실행되고 이로 인해 postings의 값이 변하는 듯하다.

원인은 데이터베이스에서 글을 받아오는 함수가 하나 더 있었던 것.
여기서 다시 글의 정보를 받아오고 있었다.
이미 글을 받아오고 있다는 것을 까먹고, 시간순 정렬한 글을 받아오는 함수를 새로 만들면서 문제가 생겼던 것이다.🥲

해결
내가 하고자 했던 건 작성시간 순서대로 글을 받아오는 것이었다.
따라서 새로 만든 함수는 삭제하고
아래 코드를 코드A의 query에 추가하자.

      ,orderBy("createdAt", "desc")

결과

  const getPostings = async () => {
    const q = query(
      collection(firestore, "postings"),
      orderBy("createdAt", "desc")
    );
    onSnapshot(q, (querySnapshot) => {
      const docData = querySnapshot.docs.map((doc) => {
        return {
          id: doc.id,
          ...doc.data(),
        };
      });
      setPostings(docData);
    });
  };

추가)
데이터를 실시간으로 받아오지 않으려면, onSnapshot대신 getDocs 메서드 사용

getDocs메서드는 forEach를 쓰기 때문에 데이터에서 문서를 가져오는 문서 갯수 만큼 렌더링 된다.

const getPostings = async () => {
    const q = query(collection(firestore, "postings"));
    const querySnapshot = await getDocs(q);
    querySnapshot.forEach((doc) => {
      const postingObj = {
        ...doc.data(),
        id: doc.id,
      };
      setPostings((prev) => [postingObj, ...prev]);
    });
  };
  
useEffect(()=>{
	getPostings();
})
profile
no tomorrow without joy

0개의 댓글