Home > Enterprise >  How to create a reactive statement in Svelte with Firebase's onSnapshot?
How to create a reactive statement in Svelte with Firebase's onSnapshot?

Time:05-30

I'm learning Svelte for the past 4 days and I'm trying to integrate it with Firebase.

I need to listen to a document named after the user's uid after the user logged in which I saved in a writable name userStore.

Note: My background was React and this can be done easily with useEffect

I need a way to call unsubscribe in the onDestroy statement... How can I do that?

    onDestroy(() => {
        unsubscribe();
    });

This is my current code:

    $: if ($userStore)
        onSnapshot(doc(db, 'userInfo', $userStore.uid), (doc) => {
            if (doc.data()) {
                console.log(doc.data());
                userInfoStore.set(doc.data() as UserInfo);
            }
        });

CodePudding user response:

I think onSnapshot() returns unsubscribe, so it should work like this

<script>

    let unsubscribe

    onDestroy(() => {
        if(unsubscribe) unsubscribe();
    });

    $: if ($userStore) {
        unsubscribe =  onSnapshot(doc(db, 'userInfo', $userStore.uid), (doc) => {
            if (doc.data()) {
                console.log(doc.data());
                userInfoStore.set(doc.data() as UserInfo);
            }
        });
    }

</script>

Is the component destroyed when the user logs out? Because the unsubcription should be called if the user logs out? I think in a component might not be the best place to handle the logic. This would be a way via a custom store

userInfoStore.js
export const userInfoStore = (() => {
        const initialValue = {}
        const {subscribe, set} = writable(initialValue)

        let unsubSnapshot

        return {
            subscribe,

            startListener(uid) {
                unsubSnapshot = onSnapshot(doc(db, 'userInfo', uid), (doc) => {
                    if (doc.data()) {
                        console.log(doc.data());
                        set(doc.data() as UserInfo);
                    }
                });
            },

            stopListener() {
                if(unsubSnapshot) unsubSnapshot()
            }
        }
    })();
auth.js
onAuthStateChanged(auth, user => {
        if(user) {
            userStore.set(user)
            userInfoStore.startListener(user.uid)
        }else {
            userInfoStore.stopListener()
        }
    })
App.svelte (main component)

Don't know how important that is or if the listener is stopped anyway when the page is closed

<script>
import {onDestroy} from 'svelte'
import {userInfoStore} './userInfoStore'

 onDestroy(() => {
        userInfoStore.stopListener()
    });
</script>
  • Related