Home > Back-end >  Firebase and Nuxt3: How to detach onSnapshot listener?
Firebase and Nuxt3: How to detach onSnapshot listener?

Time:06-13

I am using the Firestore onSnapshot listener in a component in my Nuxt3 app. I am wondering how to detach the listener when the component is unMounted. How do I successfully detach the listener? I assume I could call the unsubscribe listener in the onUnMounted hook?

I have set up the listener in an onMounted() and detached hook like so:

<script setup>
import { useUserStore } from '@/stores/user'
import {
  onSnapshot,
  collection,
  query,
  where,
  getDocs
} from 'firebase/firestore'

const userStore = useUserStore()
const loading = ref(false)
const userPosts = reactive([])
const unsubscribe = ref(null)

onMounted(async () => {
  const { firestore } = useFirebase()
  const userPostsRef = collection(firestore, 'posts')
  const q = query(userPostsRef, where('uid', '==', userStore.userProfile.uid))
  unsubscribe.value = onSnapshot(q, (snapshot) => {
    snapshot.docChanges().forEach((change) => {
      if (change.type === 'added') {
        console.log('added', change.doc.data())
        userPosts.push(change.doc.data())
      }
      if (change.type === 'modified') {
        console.log('modified', change.doc.data())
        userPosts.splice(
          userPosts.findIndex((post) => post.id === change.doc.id),
          1,
          change.doc.data()
        )
      }
      if (change.type === 'removed') {
        console.log('removed', change.doc.data())
        userPosts.splice(
          userPosts.findIndex((post) => post.id === change.doc.id),
          1
        )
      }
    })
  })
  loading.value = false
})

onUnmounted(() => {
  unsubscribe.value //<-----is this the correct way to detach it?
})

Edit: I just confirmed that the above method does not remove the listener because every time I navigate away from the page, I get the console logs of ('added', 'modified', etc). SO, I must be doing something wrong.

CodePudding user response:

The unsubscribe is a function so you'll have to call it as shown below:

onUnmounted(() => {
  // call only when unsubscribe is not null
  unsubscribe.value && unsubscribe.value()

  // or use optional chaining
  unsubscribe.value?.();
})
  • Related