arrayUnion(tags)는 태그 배열을 여러 요소가 아니라 배열 하나로 전달합니다. Firestore Standard edition은 배열 안에 배열을 허용하지 않으므로 Nested arrays are not supported 오류가 발생합니다. 여러 값을 추가하려면 arrayUnion(...tags)처럼 펼쳐서 전달합니다.
오류 증상: arrayUnion에 배열을 넣자 중첩 배열 오류가 난다
화면에서 선택한 태그가 ["react", "firebase"]처럼 배열로 준비되어 있을 때 다음처럼 그대로 넘기기 쉽습니다.
const tags = ["react", "firebase"];
arrayUnion(tags);
하지만 Firestore Web SDK가 쓰기 데이터를 직렬화하는 단계에서 아래 오류가 발생합니다.
Function arrayUnion() called with invalid data.
Nested arrays are not supported (found in document posts/post-1)
Firebase JavaScript SDK 공개 이슈에도 같은 오류 문구가 보고되었고, 작성자는 실제 데이터에 배열 안의 배열이 있었다고 확인했습니다. 이 오류는 Rules 거부나 네트워크 장애가 아니라 전송할 값의 구조가 잘못된 경우입니다.
환경·재현 조건: 서버에 쓰지 않고 직렬화 단계만 확인한다
검증 환경: Node.js 24.19.0, Firebase Web SDK 12.19.0, ESM 모듈. writeBatch().update()로 쓰기 명령을 구성하되 commit()은 호출하지 않았습니다. 따라서 실제 Firebase 프로젝트·인증·Rules 없이 동일한 직렬화 오류를 재현할 수 있습니다.
먼저 패키지를 설치합니다.
npm install firebase@12.19.0
repro-array-union.mjs · 원래 코드
import { initializeApp } from "firebase/app";
import { arrayUnion, doc, getFirestore, writeBatch } from "firebase/firestore";
const app = initializeApp({ projectId: "blogflow-repro" }, "array-union-repro");
const db = getFirestore(app);
const tags = ["react", "firebase"];
try {
writeBatch(db).update(doc(db, "posts", "post-1"), {
tags: arrayUnion(tags),
});
console.log("검증 통과");
} catch (error) {
console.error(error.message);
process.exitCode = 1;
}
node repro-array-union.mjs를 실행하면 arrayUnion(tags)를 해석하는 시점에 종료 코드 1로 실패합니다.
원인: arrayUnion은 배열 한 개가 아니라 여러 요소를 받는다
JavaScript API의 함수 시그니처는 arrayUnion(...elements)입니다. 인수 하나하나가 Firestore 배열에 추가할 요소입니다.
arrayUnion("react", "firebase"): 문자열 요소 두 개를 전달arrayUnion(tags): 배열 요소 한 개를 전달arrayUnion(...tags): 배열을 펼쳐 문자열 요소 두 개를 전달

Firestore Standard edition의 배열에는 다른 배열을 요소로 넣을 수 없습니다. 그래서 arrayUnion(tags)가 만들려는 구조는 개념적으로 [["react", "firebase"]]가 되어 거부됩니다.
변경 코드: 펼침 연산자로 태그를 개별 인수로 전달한다
fix-array-union.mjs · 수정 코드
import { initializeApp } from "firebase/app";
import { arrayUnion, doc, getFirestore, writeBatch } from "firebase/firestore";
const app = initializeApp({ projectId: "blogflow-repro" }, "array-union-fix");
const db = getFirestore(app);
const tags = ["react", "firebase"];
try {
writeBatch(db).update(doc(db, "posts", "post-1"), {
tags: arrayUnion(...tags),
});
console.log(`전달 요소: ${JSON.stringify(tags)}`);
console.log("Firestore 직렬화 검증 통과");
} catch (error) {
console.error(error.message);
process.exitCode = 1;
}
수정은 괄호 안에 ...를 추가하는 한 줄이지만 의미는 분명합니다. tags 배열을 하나의 값으로 전달하지 않고 각 문자열을 독립된 인수로 전달합니다. 공식 Firestore 문서도 여러 항목을 추가할 때 여러 인수를 사용하거나 배열에 펼침 연산자를 적용하는 예제를 제공합니다.
실제 검증 결과: 같은 입력에서 실패와 통과를 비교했다
| 실행 | 입력 | 기대 결과 | 실제 결과 | 종료 |
|---|---|---|---|---|
| 원래 코드 | arrayUnion(tags) |
중첩 배열 오류 | Nested arrays are not supported |
1 |
| 수정 코드 | arrayUnion(...tags) |
직렬화 통과 | ["react","firebase"] 전달 후 통과 |
0 |
두 파일을 실제로 실행했고, 원래 코드는 문서 경로 posts/post-1에서 실패했습니다. 수정 코드는 동일한 태그 배열을 사용하면서 오류 없이 쓰기 명령을 구성했습니다.
적용 한계: 펼침 연산자가 모든 배열 문제를 해결하지는 않는다
- 이번 검증은
commit()전 직렬화 단계까지입니다. 실제 원격 저장, 인증, Security Rules, 네트워크 성공은 검증하지 않았습니다. arrayUnion()은 기존 배열에 없는 요소만 추가합니다. 원하는 순서에 끼워 넣거나 특정 위치를 수정하는 API는 아닙니다.- 객체도 요소로 전달할 수 있지만, 객체의 일부 키만 같은 경우가 아니라 전체 값이 같은지를 기준으로 중복 여부가 판단됩니다.
- Standard edition에서 실제로 중첩 배열 구조가 필요하다면 배열 대신 map 객체 등 다른 데이터 구조를 설계해야 합니다.
tags가 빈 배열일 때 업데이트 자체를 생략할지는 애플리케이션 정책으로 정해야 합니다.
이어서 학습하기
- Firestore CRUD 사용법: 컬렉션 구조와 읽기 쓰기 흐름
- Firestore undefined 오류 해결: 선택 필드가 저장을 막을 때
- Firebase 실무 오류 해결 모음
공식 자료와 공개 사례
이 글이 도움이 되었나요?
Firebase 학습 순서
필수 13개 · 전체 19개
읽음 기록 관리
전체 과정 목차 (19개)
- 필수 길잡이 · Firebase 실무 로드맵: Auth, Firestore, Storage, Functions
- 필수 학습 · Firebase 초기화 구조: Next.js firebase.ts 설계 기준
- 필수 학습 · Firebase Authentication 사용 기준: 로그인 유지와 비밀번호 재설정
- 필수 학습 · Firebase 보안 규칙 설계: Firestore와 Storage 권한 관리하기
- 필수 학습 · Firestore CRUD 사용법: 컬렉션 구조와 읽기 쓰기 흐름
- 필수 학습 · Firebase Auth Context 설계: 로그인 권한과 라우팅 관리하기
- 필수 학습 · Firebase Storage 이미지 업로드 사용법: 상품 이미지 관리 흐름 만들기
- 필수 학습 · Firebase Custom Claims 사용법: 관리자 권한 구분하기
- 필수 학습 · Firebase Functions v2 사용법: 트리거 배포 Secret 처리
- 필수 학습 · Firestore seed data 설계: 리뷰 더미 데이터 구조 잡기
- 선택 참고 · Firebase 배포 제외 파일 설정: firebase.json의 ignore 사용법
- 선택 참고 · Firebase Firestore 인덱스 삭제 질문 해결: 배포 중 안전하게 판단하기
- 선택 참고 · Firebase Auth unauthorized-domain 오류 해결: 로그인 도메인 설정 확인
- 선택 참고 · Firebase permission-denied 오류 해결: Firestore Rules 체크리스트
- 선택 참고 · Firebase Storage 이미지 오류 해결: 403·404·token·Rules 확인법
- 선택 참고 · Firebase CORS 오류 해결: Storage 이미지 업로드가 막힐 때 확인할 설정
- 필수 선수 · Firebase 실무 오류 해결 모음: Storage, Firestore, Auth 체크리스트
- 필수 학습 · Firestore undefined 오류 해결: 선택 필드가 저장을 막을 때
- 필수 학습 · Firestore arrayUnion 중첩 배열 오류: 배열을 그대로 넘기면 실패하는 이유 현재 글
새 글 받아보기
RSS 리더에서 BlogFlow의 새 글을 확인할 수 있습니다.