@@ -5,7 +5,7 @@ import * as logger from "firebase-functions/logger";
55
66const LOCATION = "asia-northeast3" ;
77const DELETE_BATCH_SIZE = 200 ;
8- const CLEANUP_QUERY_BATCH_SIZE = 100 ;
8+ const QUERY_BATCH_SIZE = 100 ;
99
1010export const removeTodoNotificationDocuments = onDocumentDeleted ( {
1111 document : "users/{userId}/todoLists/{todoId}" ,
@@ -63,45 +63,76 @@ export const removeCompletedTodoReceipts = onDocumentUpdated({
6363 }
6464) ;
6565
66- export const removeExpiredCompletedTodoReceipts = onSchedule ( {
66+ export const removeStaleTodoReceipts = onSchedule ( {
6767 region : LOCATION ,
6868 schedule : "0 * * * *" ,
6969 timeZone : "UTC"
7070 } ,
7171 async ( ) => {
7272 try {
73- let lastDoc : FirebaseFirestore . QueryDocumentSnapshot < FirebaseFirestore . DocumentData > | undefined ;
73+ let lastExpiredCompletedTodo :
74+ FirebaseFirestore . QueryDocumentSnapshot < FirebaseFirestore . DocumentData > | undefined ;
7475
7576 while ( true ) {
7677 let query = admin . firestore ( )
7778 . collectionGroup ( "todoLists" )
79+ . where ( "isCompleted" , "==" , true )
7880 . where ( "dueDate" , "<" , admin . firestore . Timestamp . now ( ) )
7981 . orderBy ( "dueDate" )
80- . limit ( CLEANUP_QUERY_BATCH_SIZE ) ;
82+ . limit ( QUERY_BATCH_SIZE ) ;
8183
82- if ( lastDoc ) {
83- query = query . startAfter ( lastDoc ) ;
84+ if ( lastExpiredCompletedTodo ) {
85+ query = query . startAfter ( lastExpiredCompletedTodo ) ;
8486 }
8587
8688 const snapshot = await query . get ( ) ;
87- if ( snapshot . empty ) { return ; }
89+ if ( snapshot . empty ) { break ; }
8890
8991 for ( const todoDoc of snapshot . docs ) {
90- const todoData = todoDoc . data ( ) ;
91- if ( todoData . isCompleted !== true ) { continue ; }
92-
9392 const userId = todoDoc . ref . parent . parent ?. id ;
9493 if ( ! userId ) { continue ; }
9594
9695 await deleteByTodoId ( userId , "notificationReceipts" , todoDoc . id ) ;
9796 }
9897
99- if ( snapshot . size < CLEANUP_QUERY_BATCH_SIZE ) { return ; }
100- lastDoc = snapshot . docs [ snapshot . docs . length - 1 ] ;
98+ if ( snapshot . size < QUERY_BATCH_SIZE ) { break ; }
99+ lastExpiredCompletedTodo = snapshot . docs [ snapshot . docs . length - 1 ] ;
101100 }
102101 } catch ( error ) {
103102 logger . error ( "지난 마감일의 완료된 todo receipt 정리 실패" , { error } ) ;
104103 }
104+
105+ try {
106+ let lastTodoWithoutDueDate :
107+ FirebaseFirestore . QueryDocumentSnapshot < FirebaseFirestore . DocumentData > | undefined ;
108+
109+ while ( true ) {
110+ let query = admin . firestore ( )
111+ . collectionGroup ( "todoLists" )
112+ . where ( "dueDate" , "==" , null )
113+ . orderBy ( admin . firestore . FieldPath . documentId ( ) )
114+ . limit ( QUERY_BATCH_SIZE ) ;
115+
116+ if ( lastTodoWithoutDueDate ) {
117+ query = query . startAfter ( lastTodoWithoutDueDate ) ;
118+ }
119+
120+ const snapshot = await query . get ( ) ;
121+ if ( snapshot . empty ) { break ; }
122+
123+ for ( const todoDoc of snapshot . docs ) {
124+ const userId = todoDoc . ref . parent . parent ?. id ;
125+ if ( ! userId ) { continue ; }
126+
127+ await deleteByTodoId ( userId , "notificationReceipts" , todoDoc . id ) ;
128+ }
129+
130+ if ( snapshot . size < QUERY_BATCH_SIZE ) { break ; }
131+ lastTodoWithoutDueDate = snapshot . docs [ snapshot . docs . length - 1 ] ;
132+ }
133+ } catch ( error ) {
134+ logger . error ( "마감일이 없는 todo receipt 정리 실패" , { error } ) ;
135+ }
105136 }
106137) ;
107138
0 commit comments