Currently, I am utilizing Vue 3 to develop a Firebase composable that is responsible for subscribing to an onSnapshot()
stream.
I have been attempting to unsubscribe from this stream by invoking the returned unsubscribe()
function within both watchEffect
and onInvalidate
. For more information on these functions, you can refer to the corresponding section in the Vue documentation.
By utilizing a console.log()
, it has been confirmed that my watchEffect
is indeed being triggered.
However, I seem unable to activate the second console.log()
statement located inside the onInvalidate
block. Consequently, uncertainty arises regarding whether the unsubscribe()
function is being executed at all.
Given the code snippet provided below, why is it that the
console.log("unsubscribe fired");
never actually runs?
Is there an alternative method to ensure that I have successfully unsubscribed from the Firestore stream? Perhaps through logging in the Firebase dashboard or similar means?
Below is the TypeScript implementation of the Vue Firestore composable:
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;