1
+ import { useMutation , useQueryClient } from "@tanstack/react-query" ;
1
2
import {
2
3
useAddDocumentMutation ,
3
4
useCollectionQuery ,
8
9
doc ,
9
10
getFirestore ,
10
11
query ,
12
+ Timestamp ,
11
13
where ,
12
14
} from "firebase/firestore" ;
13
15
import { useState } from "react" ;
@@ -17,7 +19,7 @@ interface Task {
17
19
title : string ;
18
20
completed : boolean ;
19
21
priority : "low" | "medium" | "high" ;
20
- createdAt : Date ;
22
+ createdAt : Timestamp | Date ;
21
23
}
22
24
23
25
export function CollectionQueryExample ( ) {
@@ -26,6 +28,7 @@ export function CollectionQueryExample() {
26
28
useState < Task [ "priority" ] > ( "medium" ) ;
27
29
const [ filterCompleted , setFilterCompleted ] = useState < boolean | null > ( null ) ;
28
30
31
+ const queryClient = useQueryClient ( ) ;
29
32
const firestore = getFirestore ( ) ;
30
33
const tasksCollection = collection ( firestore , "tasks" ) ;
31
34
@@ -45,8 +48,13 @@ export function CollectionQueryExample() {
45
48
queryKey : [ "tasks" , filterCompleted ] ,
46
49
} ) ;
47
50
48
- // Add task mutation
49
- const addTaskMutation = useAddDocumentMutation ( tasksCollection ) ;
51
+ // Add task mutation with query invalidation
52
+ const addTaskMutation = useAddDocumentMutation ( tasksCollection , {
53
+ onSuccess : ( ) => {
54
+ // Invalidate all task queries after successful add
55
+ queryClient . invalidateQueries ( { queryKey : [ "tasks" ] } ) ;
56
+ } ,
57
+ } ) ;
50
58
51
59
const handleAddTask = async ( ) => {
52
60
if ( ! newTaskTitle . trim ( ) ) return ;
@@ -76,10 +84,21 @@ export function CollectionQueryExample() {
76
84
console . log ( `Would toggle task ${ taskId } to ${ ! currentCompleted } ` ) ;
77
85
} ;
78
86
87
+ // Use a mutation for delete with dynamic document reference TODO: why doesn't the library support dynamic document reference?
88
+ const deleteTaskMutation = useMutation ( {
89
+ mutationFn : async ( taskId : string ) => {
90
+ const taskRef = doc ( firestore , "tasks" , taskId ) ;
91
+ await deleteDoc ( taskRef ) ;
92
+ } ,
93
+ onSuccess : ( ) => {
94
+ // Invalidate all task queries after successful delete
95
+ queryClient . invalidateQueries ( { queryKey : [ "tasks" ] } ) ;
96
+ } ,
97
+ } ) ;
98
+
79
99
const handleDeleteTask = async ( taskId : string ) => {
80
- const taskRef = doc ( firestore , "tasks" , taskId ) ;
81
100
try {
82
- await deleteDoc ( taskRef ) ;
101
+ await deleteTaskMutation . mutateAsync ( taskId ) ;
83
102
} catch ( error ) {
84
103
console . error ( "Failed to delete task:" , error ) ;
85
104
}
@@ -252,7 +271,12 @@ export function CollectionQueryExample() {
252
271
{ task . title }
253
272
</ h4 >
254
273
< p className = "text-sm text-gray-500" >
255
- Created: { task . createdAt . toLocaleDateString ( ) }
274
+ Created:{ " " }
275
+ { task . createdAt instanceof Timestamp
276
+ ? task . createdAt . toDate ( ) . toLocaleDateString ( )
277
+ : task . createdAt instanceof Date
278
+ ? task . createdAt . toLocaleDateString ( )
279
+ : "Unknown date" }
256
280
</ p >
257
281
</ div >
258
282
< span
0 commit comments