【问题标题】:Remove multiple firebase listeners at once一次删除多个 Firebase 侦听器
【发布时间】:2021-08-13 05:40:29
【问题描述】:

我正在创建一个带有 react native 的应用程序,并面临一个问题,即我在整个应用程序中创建了多个 firebase 监听器,准确地说是在不同屏幕上创建监听器,以及监听 firebase-database 和其他监听 firestore 的监听器。

我想要完成的是通过一次呼叫或在必要时使用多行但尽可能紧凑的方式杀死所有这些听众 - 以及从听众甚至没有运行的完全不同的屏幕,这很重要。

我知道可以使用 Firebase.goOffline(),但这只会使我与 Firebase 断开连接 - 它不会阻止听众。我一再goOnline(),听众都回来了。

我还没有从谷歌等找到任何解决这个问题的方法,这就是为什么我现在尝试在这里提问,如果有人知道如何处理这种行为,我会很高兴。

以下代码示例为您提供了我在应用程序中包含的侦听器,它们位于同一屏幕中,但我在其他屏幕中几乎相同。

数据库监听器:

const statusListener = () => {
        var partnerRef = firebase.database().ref(`users/${partnerId}/onlineState`);
        partnerRef.on('value', function(snapshot){
            setPartnerState(snapshot.val())
        })
    };

Firestore 监听器:(这个很长,那只是因为我过滤了从监听器中检索到的文档)

const loadnewmessages = () =>{ firebase.firestore().collection("chatrooms").doc(`${chatId}`).collection(`${chatId}`).orderBy("timestamp").limit(50).onSnapshot((snapshot)  => {
            var newmessages = [];
            var deletedmesssages = [];
            snapshot.docChanges().forEach((change) => {
                if(change.type  === "added"){
                    newmessages.push({
                        counter: change.doc.data().counter,
                        sender: change.doc.data().sender,
                        timestamp: change.doc.data().timestamp.toString(),
                        value: change.doc.data().value,
                        displayedTime: new Date(change.doc.data().displayedTime)
                    })
                };
                if(change.type  === "removed"){
                    deletedmesssages.push({
                        counter: change.doc.data().counter,
                        sender: change.doc.data().sender,
                        timestamp: change.doc.data().timestamp.toString(),
                        value: change.doc.data().value,
                        displayedTime: new Date(change.doc.data().displayedTime)
                    })
                };

            })
            if(newmessages.length > 0){
                setChatMessages(chatmessages => {
                    return chatmessages.concat(newmessages)
                });
            };
            if(deletedmesssages.length > 0){
                setChatMessages(chatmessages => {
                    var modifythisarray = chatmessages;
                    let index = chatmessages.map(e => e.timestamp).indexOf(`${deletedmesssages[0].timestamp}`);
                    let pasttime = Date.now() - parseInt(modifythisarray[index].timestamp);
                    modifythisarray.splice(index, 1);
                    if(pasttime > 300000){
                        return chatmessages
                    }else{
                        return modifythisarray
                    }
                });
                setRefreshFlatList(refreshFlatlist => {
                    //console.log("Aktueller Status von refresher: ", refreshFlatlist);
                    return !refreshFlatlist
                });
            }
            newmessages = [];
            deletedmesssages = [];
        })
    };

这两个监听器都在 useEffect 钩子中调用,就像这样:(useEffect 末尾带有空括号确保这些监听器只被调用一次而不是多次。)

useEffect(() => {
        loadnewmessages();
        statusListener();
    }, []); 

【问题讨论】:

  • 你能添加一些代码来详细说明你是如何注册监听器的吗?
  • @DanielDuong 确定,我刚刚添加了两个示例!一个监听器连接到数据库,一个监听器连接到 firestore。
  • 这里没有简写:您需要跟踪侦听器并将其删除,如两种产品的文档中所示(FirestoreRealtime Database)。
  • 但是如果我的听众在一个聊天屏幕上,我想从另一个屏幕组件中注销用户呢?我将无法访问这两个听众。离开聊天屏幕后,我需要立即停止听众。一旦我回到屏幕,监听器就会重新激活并再次下载所有 2o 文件,这让我的账单变得昂贵,因为监听器第一次上线时,它会下载所有 20 个最近创建的文件。

标签: javascript firebase react-native firebase-realtime-database google-cloud-firestore


【解决方案1】:

所有订阅函数都返回取消订阅函数

const unSubscriptions = [];

... Where you subscribe
const unSub = document.onSnapshot(listener);
subscriptions.push(unSub);

... Where you unsubscribe all
function unSubAll () {
   unSubscriptions.forEach((unSub) => unSub());
   // Clear the array
   unSubscriptions.length = 0;
}

【讨论】:

  • 工作正常,但有一个问题!根据它是 Firestore 还是数据库侦听器,您需要以不同的方式停止它们。数据库使用 .off() 并使用 firestore,您需要像上面那样进行操作。您的解决方案基本上仅适用于 firestore 侦听器 :)
  • 请记住,在 javascript 中,函数是一等公民。所以与其叫停。您可以将其推送到 unSubscriptions 数组。 unSubscriptions.push(databaseRef.off);
猜你喜欢
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
  • 2015-09-07
  • 2014-02-27
  • 2017-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多