如何使用 Firebase 的 onSnapshot 在 Svelte 中创建反应语句?

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

过去 4 天我一直在学习 Svelte,我正在尝试将它与 Firebase 集成。

我需要在用户登录后监听一个以用户uid命名的文件,我保存在一个可写的名字userStore中。

注意:我的背景是 React,这可以通过 useEffect

轻松完成

我需要一种在 onDestroy 语句中调用取消订阅的方法...我该怎么做?

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

这是我当前的代码:

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

我觉得onSnapshot()returnsunsubscribe,所以应该是这样的

<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>

用户退出时组件是否被销毁?因为如果用户注销应该调用取消订阅?我认为在组件中可能不是处理逻辑的最佳位置。这将是通过自定义商店的一种方式

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(主要成分)

不知道这有多重要,或者当页面关闭时监听器是否停止了

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

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