I am using Vue 3 to create a Firebase composable that subscribes to an onSnapshot()
stream.
And I am trying to unsunscribe from that stream by calling the returned unsubscribe()
function inside watchEffect
and onInvalidate
. Here are the Vue docs that explain those particular functions.
Using a console.log()
I can confirm my watchEffect
is firing.
But I cannot trigger my second console.log()
that exists inside onInvalidate
, and therefore I'm not sure if the unsubscribe()
function is ever called.
In the code below, why doesn't my console.log("unsubscribe fired");
ever fire?
How else can I be sure I am unsubscribed from the Firestore stream? Is there a log of this inside the Firebase dashboard or something similar?
Here is the Vue Firestore composable (it is written in TypeScript):
import { ref, reactive, watchEffect } from "vue";
import { projectFirestore } from "@/firebase/config";
import {
query,
orderBy,
onSnapshot,
DocumentData,
collection,
} from "firebase/firestore";
const useCollection: any = (col: any) => {
const documents = reactive<Record<string, unknown>[]>([]);
const error = ref<string | null>(null);
// references
const collectionReference = collection(projectFirestore, col);
const collectionOrdered = query(
collectionReference,
orderBy("createdAt", "desc")
);
// updates
const unsubscribe = onSnapshot(
collectionOrdered,
(snapshot) => {
snapshot.docs.forEach((doc: DocumentData) => {
documents.push({ ...doc.data(), id: doc.id });
});
error.value = null;
console.log(documents);
},
(err) => {
console.log(err.message);
documents.splice(0);
error.value = err.message;
}
);
watchEffect((onInvalidate) => {
console.log("watchEffect fired"); //This fires
onInvalidate(() => {
unsubscribe();
console.log("unsubscribe fired"); //This does not fire
});
});
return { documents, error };
};
export default useCollection;
Because you haven't any reactive object in your callback of watchEffect