Published on

Firebase function에서 객체 참조 문제

Authors

배경

현재 사이드 프로젝트를 Firebase 기반으로 개발하고 있다. Firebase Firestore, Functions, Storage 등등 백엔드를 전부 맡겼다.

그런데, Functions 작성 중 이상한 에러가 발생하기 시작했다.

문제

다음은 firebase function에서 인벤토리에서 아이템을 장착하면 새롭게 내가 장착한 아이템으로 내 정보를 갱신하는 부분 중 일부의 코드이다. 다음 중 잘못된 내용은 무엇일까?

export const EmptyEqquipedItems: EquippedItems = {
  [ItemCategory.top]: null,
  [ItemCategory.hat]: null,
  [ItemCategory.shoes]: null,
  [ItemCategory.hand]: null,
  [ItemCategory.acc]: null,
};

const newEquippedItems: EquippedItems = EmptyEqquipedItems;

itemsQuery.forEach((doc) => {
  const item: Item = doc.data() as any;
  newEquippedItems[item.category] = {
    ...item,
    id: doc.id,
  };
});
console.log('4. equippedItems', newEquippedItems);

코드만 보면은 전혀 문제가 없어 보인다. 하지만 실행했을 때는 달랐다.

한 번 장착한 아이템들이 도무지 없어지지 않았다. 이게 무슨 일이지?

현상 1) 나는 분명 모자 1개를 장착했는데, 아이템이 없어지지 않는다.

현상 2) 아무것도 장착하지 않기(아이템 벗기)를 호출했는데도 여전히 newEquippedItems에는 이전에 내가 장착했던 아이템들이 포함되어 있었다.

비어있어야 할 새로운 변수 newEquippedItems에 값이 있다니, 이상하다. 분명 나는 EmptyEqquipedItems를 할당해 주었는데 여기에 그럼 이전에 입은 아이템이 계속 남아있는 것일까..?

해결하기

정말 그런 것이었다.

Firebase Function가 어떤 인스턴스에서 실행되는 지는 자세히는 모르겠지만 그런 것이었다. 그래서 위 코드 중 일부를

const newEquippedItems: EquippedItems = { ...EmptyEqquipedItems };

이렇게, 같은 객체가 아니고 완전히 새로운 객체 형태로 구조분해할당해 주었다.

그러니까 귀신같이 문제가 해결.

EmptyEqquipedItems 객체의 경우 models.ts 파일에 별도로 선언되어 있었는데, 이 객체는 객체일 뿐, 무언가 할당되어 있을 것이라고는 상상도 못했다. 아마 한 번 빌드된 function이 메모리에 머물러 있고 계속해서 같은 EmptyEqquipedItems 객체가 호출되어 갱신되어서 그런 것 같다. 이름만 EmptyEqquipedItems 이고 바보같이 자꾸 업데이트 하고 있던 셈이다.

앞으로 할 일

server side에서 이렇게 나이브하게 코드를 작성하면 전혀 예상치 못한 일이 일어날 수 있다는 것을 깨달았다. 다음부터는 객체 참조 문제를 조심하도록!! (다행인 것은 에러가 나는 로직이 길지 않아 빠르게 디버깅해낼 수 있었다)