reactjsfirebasefirebase-authenticationgoogle-cloud-functionsreact-query

How to remove data on logout when using firebase and react query?


When my user logs out, I want to remove all user data from the app, but I'm having trouble implementing this.

I have a custom useUserData() hook that gets the user's data. getUser() is a callable cloud function. This is my code so far.

import { useEffect, useState } from "react"
import { useQuery, useQueryClient } from "react-query"
import { getUser } from "Services/firebase/functions"
import firebase from "firebase/app"

export default function useUserData(){
    const [ enabled, setEnabled] = useState(false)
    const queryClient = useQueryClient()

    useEffect(_ => {
        const unsubscribe = firebase.auth().onAuthStateChanged(user => {
            setEnabled(Boolean(user))
            if (!user){
                // remove data
            }
            else queryClient.invalidateQueries("user", { refetchActive: true, refetchInactive: true })
        })

        return unsubscribe()
    }, [])

    return useQuery(
        "user", 
        () => getUser().then(res => res.data),
        {
            enabled
        }
    )
}

Edit:

It seemed that I was handling my effect cleanup wrong. This seems to be working.

import { useEffect, useState } from "react"
import { useQuery, useQueryClient } from "react-query"
import { getUser } from "Services/firebase/functions"
import firebase from "firebase/app"

export default function useUserData(){
    const [ enabled, setEnabled] = useState(false)
    const queryClient = useQueryClient()
    useEffect(_ => {
        const unsubscribe = firebase.auth().onAuthStateChanged(user => {
            setEnabled(Boolean(user))    
            if (!user) {
                queryClient.removeQueries("user")
            } 
        })
        
        return _ => unsubscribe()
    }, [])

    return useQuery(
        "user", 
        () => getUser().then(res => res.data),
        {
            enabled
        }
    )
}

Weirdly enough, the query still fetches once after logging out, when the query should already be disabled.


Solution

  • Here's my current implementation which seems to work fine.

    import { useEffect, useState } from "react"
    import { useQuery, useQueryClient } from "react-query";
    import firebase from "firebase/app"
    
    export default function useAuthenticatedQuery(key, func, options){
        const [ enabled, setEnabled] = useState(false)
        const queryClient = useQueryClient()
        useEffect(_ => {
            const unsubscribe = firebase.auth().onAuthStateChanged(user => {
                setEnabled(Boolean(user))    
                if (!user){
                    queryClient.setQueryData(key, _ => undefined)
                    queryClient.removeQueries(key, _ => undefined)
                }else 
                    queryClient.invalidateQueries(key, { refetchActive: true, refetchInactive: true })
            })
            return _ => unsubscribe()
            // eslint-disable-next-line
        }, [])
    
        return useQuery(
            key,
            func,
            {
                ...options,
                enabled
            }
        )
    }
    

    I use it just like the regular useQuery hook:

    import useAuthenticatedQuery from "Hooks/useAuthenticatedQuery"
    
    export default function useUserData(){
    
        return useAuthenticatedQuery(
            "user", 
            () => getUser().then(res => res.data)
        )
    }