Skip to content

[#347] Firebase 스케줄러가 동작하지 않아 Todo가 제거되지 않는 현상을 해결한다#348

Merged
opficdev merged 10 commits intodevelopfrom
fix/#347-schedular
Apr 3, 2026
Merged

[#347] Firebase 스케줄러가 동작하지 않아 Todo가 제거되지 않는 현상을 해결한다#348
opficdev merged 10 commits intodevelopfrom
fix/#347-schedular

Conversation

@opficdev
Copy link
Copy Markdown
Owner

@opficdev opficdev commented Apr 2, 2026

@opficdev opficdev self-assigned this Apr 2, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이번 PR은 isDeleted 필드에 대한 Firestore 인덱스 설정을 추가하고, 에러 처리 방식을 toError 유틸리티로 표준화하여 로깅의 일관성을 높였습니다. 또한 할 일 및 알림 관련 정리 로직을 재구성하였습니다. 다만, 정리 작업 시 페이지네이션 로직이 제거되어 발생할 수 있는 무한 루프 위험과 대량 데이터 처리 시의 성능 및 비용 최적화에 대한 개선이 필요합니다.

Comment on lines +212 to +221
while (true) {
const collectionPath = collectionName === "notificationDispatches" ?
FirestorePath.notificationDispatches(userId) :
FirestorePath.notifications(userId);
const snapshot = await admin.firestore()
.collection(collectionPath)
.where("todoId", "==", todoId)
.limit(DELETE_BATCH_SIZE)
.get();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

deleteByTodoId 함수 내의 while (true) 루프가 삭제 작업의 즉각적인 반영에 의존하고 있습니다. 삭제된 문서가 다음 조회에서 다시 반환될 경우 무한 루프가 발생할 수 있으므로, startAfter를 사용하여 이미 처리한 문서를 건너뛰도록 수정이 필요합니다.

Comment on lines +116 to +122
export const cleanupUnusedTodoNotificationRecords = onSchedule({
maxInstances: 1,
region: LOCATION,
schedule: "0 * * * *",
timeZone: "UTC"
},
async () => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

cleanupUnusedTodoNotificationRecords 함수는 매시간 모든 사용자의 완료된 Todo를 조회하고 각 Todo마다 개별 삭제 작업을 수행합니다. 이는 데이터 증가 시 Firestore 비용 상승과 성능 저하를 유발할 수 있습니다. Promise.all을 통한 병렬 처리나 TTL 정책 활용 등 더 효율적인 정리 방식을 고려해 보세요.

@opficdev
Copy link
Copy Markdown
Owner Author

opficdev commented Apr 2, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이 PR은 normalizeError 함수를 toError로 리팩토링하여 Firebase 함수 전반의 오류 로깅을 간소화합니다. 또한, notification/cleanup.ts에 새로운 정리 함수들을 추가하여 todo 삭제 시 관련 알림 및 발송 기록을 자동으로 제거하고, 완료되었거나 마감일이 없는 todo의 발송 기록을 정리합니다. 기존의 soft-delete 정리 함수들도 문서 ID 기반 페이지네이션을 사용하도록 개선되었습니다. 코드 리뷰에서는 notifications, todoLists, webPages 컬렉션 그룹에 대한 특정 쿼리(예: isDeleted 필터링 및 documentId 정렬)에 필요한 복합 인덱스가 firestore.index.json에 누락되어 런타임 오류가 발생할 수 있음을 지적했습니다.

Comment on lines 90 to +91
.where("isDeleted", "==", true)
.orderBy(admin.firestore.FieldPath.documentId())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

collectionGroup 쿼리에서 필터(where)와 정렬(orderBy)을 함께 사용하려면 복합 인덱스가 필요합니다. 현재 firestore.index.json에는 isDeleted에 대한 단일 필드 인덱스만 정의되어 있어, orderBy(admin.firestore.FieldPath.documentId())가 포함된 이 쿼리는 실행 시 오류가 발생할 수 있습니다. notifications 컬렉션 그룹에 대해 isDeleted__name__을 포함하는 복합 인덱스를 추가해야 합니다.

Comment on lines +166 to +167
.where("dueDate", "==", null)
.orderBy(admin.firestore.FieldPath.documentId())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

todoLists 컬렉션 그룹에 대한 이 쿼리 역시 dueDate 필터와 documentId 정렬을 함께 사용하므로 복합 인덱스가 필요합니다. firestore.index.jsonisCompleted가 포함된 복합 인덱스는 있지만, isCompleted 필터 없이 dueDate__name__만 사용하는 쿼리를 위한 인덱스는 누락된 것으로 보입니다.

Comment on lines 24 to 25
.where("isDeleted", "==", true)
.orderBy(admin.firestore.FieldPath.documentId())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

todoLists 컬렉션 그룹에서 isDeleted 필터와 documentId 정렬을 사용하는 이 쿼리도 복합 인덱스가 필요합니다. firestore.index.jsonfieldOverrides만으로는 이 쿼리를 지원할 수 없으므로 복합 인덱스 정의를 추가해 주세요.

Comment on lines 23 to +24
.where("isDeleted", "==", true)
.orderBy(admin.firestore.FieldPath.documentId())
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

webPages 컬렉션 그룹에 대해서도 isDeleteddocumentId를 조합한 복합 인덱스가 필요합니다. 인덱스가 없으면 스케줄러가 정상적으로 동작하지 않을 수 있습니다.

@opficdev opficdev merged commit 6ff7ce3 into develop Apr 3, 2026
1 check passed
@opficdev opficdev deleted the fix/#347-schedular branch April 3, 2026 03:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Firebase 스케줄러가 동작하지 않아 Todo가 제거되지 않는 현상을 해결한다

1 participant