Skip to content

Commit 6ff7ce3

Browse files
authored
[#347] Firebase 스케줄러가 동작하지 않아 Todo가 제거되지 않는 현상을 해결한다 (#348)
* refactor: 에러 문구가 직접보이도록 개선 * feat: todoLists 필요 인덱스 추가 * refactor: 불필요 쿼리 및 페이지네이션 제거 * chore: 인덱스 추가 * file: 지워지는 데이터 기준으로 파일 위치 이동 * feat: 푸시 알림 soft delete 및 Firestore 인덱스 관리 * feat: documentID 기준으로 오름차순 정렬하여 페이지네이션 구현 * chore: 직관적이지 않은 함수명 수정 * feat: 단일 인덱스 추가 * fix: 잘못된 스케줄링 타이머 수정
1 parent e1b9e6a commit 6ff7ce3

File tree

13 files changed

+380
-256
lines changed

13 files changed

+380
-256
lines changed

Firebase/firestore.index.json

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
{
1212
"fieldPath": "dueDate",
1313
"order": "ASCENDING"
14+
},
15+
{
16+
"fieldPath": "__name__",
17+
"order": "ASCENDING"
1418
}
1519
]
1620
},
@@ -573,5 +577,94 @@
573577
]
574578
}
575579
],
576-
"fieldOverrides": []
580+
"fieldOverrides": [
581+
{
582+
"collectionGroup": "todoLists",
583+
"fieldPath": "dueDate",
584+
"indexes": [
585+
{
586+
"order": "ASCENDING",
587+
"queryScope": "COLLECTION"
588+
},
589+
{
590+
"order": "DESCENDING",
591+
"queryScope": "COLLECTION"
592+
},
593+
{
594+
"order": "ASCENDING",
595+
"queryScope": "COLLECTION_GROUP"
596+
},
597+
{
598+
"order": "DESCENDING",
599+
"queryScope": "COLLECTION_GROUP"
600+
}
601+
]
602+
},
603+
{
604+
"collectionGroup": "todoLists",
605+
"fieldPath": "isDeleted",
606+
"indexes": [
607+
{
608+
"order": "ASCENDING",
609+
"queryScope": "COLLECTION"
610+
},
611+
{
612+
"order": "DESCENDING",
613+
"queryScope": "COLLECTION"
614+
},
615+
{
616+
"order": "ASCENDING",
617+
"queryScope": "COLLECTION_GROUP"
618+
},
619+
{
620+
"order": "DESCENDING",
621+
"queryScope": "COLLECTION_GROUP"
622+
}
623+
]
624+
},
625+
{
626+
"collectionGroup": "notifications",
627+
"fieldPath": "isDeleted",
628+
"indexes": [
629+
{
630+
"order": "ASCENDING",
631+
"queryScope": "COLLECTION"
632+
},
633+
{
634+
"order": "DESCENDING",
635+
"queryScope": "COLLECTION"
636+
},
637+
{
638+
"order": "ASCENDING",
639+
"queryScope": "COLLECTION_GROUP"
640+
},
641+
{
642+
"order": "DESCENDING",
643+
"queryScope": "COLLECTION_GROUP"
644+
}
645+
]
646+
},
647+
{
648+
"collectionGroup": "webPages",
649+
"fieldPath": "isDeleted",
650+
"indexes": [
651+
{
652+
"order": "ASCENDING",
653+
"queryScope": "COLLECTION"
654+
},
655+
{
656+
"order": "DESCENDING",
657+
"queryScope": "COLLECTION"
658+
},
659+
{
660+
"order": "ASCENDING",
661+
"queryScope": "COLLECTION_GROUP"
662+
},
663+
{
664+
"order": "DESCENDING",
665+
"queryScope": "COLLECTION_GROUP"
666+
}
667+
]
668+
}
669+
]
577670
}
Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,4 @@
1-
export function normalizeError(error: unknown): Record<string, unknown> {
2-
const normalized = error as {
3-
code?: unknown;
4-
details?: unknown;
5-
message?: unknown;
6-
stack?: unknown;
7-
};
8-
return {
9-
code: normalized?.code ?? null,
10-
details: normalized?.details ?? null,
11-
message: normalized?.message ?? String(error),
12-
stack: normalized?.stack ?? null
13-
};
1+
export function toError(error: unknown): Error {
2+
if (error instanceof Error) { return error; }
3+
return new Error(String(error));
144
}

Firebase/functions/src/fcm/notification.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { onTaskDispatched } from "firebase-functions/v2/tasks";
22
import * as admin from "firebase-admin";
33
import * as logger from "firebase-functions/logger";
44
import { formatDateKey, toDate } from "../common/date";
5-
import { normalizeError } from "../common/error";
5+
import { toError } from "../common/error";
66
import { FirestorePath } from "../common/firestorePath";
77
import { resolveTimeZone } from "./shared";
88

@@ -131,9 +131,8 @@ export const sendPushNotification = onTaskDispatched({
131131
}
132132

133133
} catch (error) {
134-
logger.error("알림 발송 중 오류 발생", {
135-
payload: req.data,
136-
error: normalizeError(error)
134+
logger.error("알림 발송 중 오류 발생", toError(error), {
135+
payload: req.data
137136
});
138137
}
139138
}

Firebase/functions/src/fcm/schedule.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { getFunctions } from "firebase-admin/functions";
33
import * as admin from "firebase-admin";
44
import * as logger from "firebase-functions/logger";
55
import { addDays, getZonedParts, zonedDateTimeToUTC } from "../common/date";
6-
import { normalizeError } from "../common/error";
6+
import { toError } from "../common/error";
77
import { FirestorePath } from "../common/firestorePath";
88
import { resolveTimeZone } from "./shared";
99

@@ -27,9 +27,8 @@ export const scheduleTodoReminder = onSchedule({
2727
try {
2828
usersSnapshot = await admin.firestore().collection("users").get();
2929
} catch (error) {
30-
logger.error("users 조회 실패", {
31-
at: "collection(users).get()",
32-
...normalizeError(error)
30+
logger.error("users 조회 실패", toError(error), {
31+
at: "collection(users).get()"
3332
});
3433
return;
3534
}
@@ -42,10 +41,9 @@ export const scheduleTodoReminder = onSchedule({
4241
.doc(FirestorePath.userData(userId, FirestorePath.UserDataDocument.settings))
4342
.get();
4443
} catch (error) {
45-
logger.error("settings 조회 실패", {
44+
logger.error("settings 조회 실패", toError(error), {
4645
userId,
47-
at: "users/{uid}/userData/settings",
48-
...normalizeError(error)
46+
at: "users/{uid}/userData/settings"
4947
});
5048
continue;
5149
}
@@ -93,13 +91,12 @@ export const scheduleTodoReminder = onSchedule({
9391
.where("dueDate", "<", admin.firestore.Timestamp.fromDate(endUTC))
9492
.get();
9593
} catch (error) {
96-
logger.error("todoLists 조회 실패", {
94+
logger.error("todoLists 조회 실패", toError(error), {
9795
userId,
9896
at: "todoLists.where(dueDate>=start).where(dueDate<end)",
9997
startUTC: startUTC.toISOString(),
10098
endUTC: endUTC.toISOString(),
101-
dueDateKey,
102-
...normalizeError(error)
99+
dueDateKey
103100
});
104101
continue;
105102
}
@@ -121,18 +118,17 @@ export const scheduleTodoReminder = onSchedule({
121118
try {
122119
await queue.enqueue(notificationPayload);
123120
} catch (error) {
124-
logger.error("Cloud Tasks enqueue 실패", {
121+
logger.error("Cloud Tasks enqueue 실패", toError(error), {
125122
userId,
126123
todoId: todoDoc.id,
127-
dueDateKey,
128-
...normalizeError(error)
124+
dueDateKey
129125
});
130126
}
131127
}
132128
}
133129

134130
} catch (error) {
135-
logger.error("알림 스케줄 배치 실행 중 오류 발생", normalizeError(error));
131+
logger.error("알림 스케줄 배치 실행 중 오류 발생", toError(error));
136132
}
137133
}
138134
);

Firebase/functions/src/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,7 @@ import {
3333
} from "./fcm/schedule";
3434

3535
import {
36-
removeTodoNotificationDocuments,
37-
removeCompletedTodoNotificationRecords,
38-
cleanupSoftDeletedTodos,
39-
cleanupUnusedTodoNotificationRecords
36+
cleanupSoftDeletedTodos
4037
} from "./todo/cleanup";
4138

4239
import {
@@ -61,6 +58,9 @@ import {
6158
} from "./notification/deletion";
6259

6360
import {
61+
removeTodoNotificationDocuments,
62+
removeCompletedTodoNotificationRecords,
63+
cleanupNotificationDispatches,
6464
cleanupSoftDeletedNotifications
6565
} from "./notification/cleanup";
6666

@@ -114,7 +114,7 @@ export {
114114
removeTodoNotificationDocuments,
115115
removeCompletedTodoNotificationRecords,
116116
cleanupSoftDeletedTodos,
117-
cleanupUnusedTodoNotificationRecords,
117+
cleanupNotificationDispatches,
118118
syncTodoNotificationCategory,
119119
requestMoveRemovedCategoryTodosToEtc,
120120
completeMoveRemovedCategoryTodosToEtc,

0 commit comments

Comments
 (0)