简体   繁体   中英

Remove multiple firebase listeners at once

Im creating an app with react native and face the problem that I create multiple firebase listeners troughout the app, listeners on different screens to be precise and also listeners that listen to the firebase-database and others listening to the firestore .

What I want to accomplish is to kill all those listeners with one call or if necessary with multiple lines but as compact as possible - and also from an entire different screen where the listeners arent even running , this is important.

I know that there is the possibility to use Firebase.goOffline() but this only disconnects me from the Firebase - it doesnt stop the listeners . As soon as I goOnline() again, the listeners are all back.

I didnt find any solution yet for this problem from google etc thats why I try to ask here now, I would appriciate if anybody would have an idea how maybe an approach how to handle this type of behavior.

The following code samples provide you with listeners I included inside my app, they are located in in the same screen but I have nearly identical ones in other screens.

Database listener:

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

Firestore Listener: (this one is very long, thats only because I filter the documents I retrieve from the listener)

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 = [];
        })
    };

Both those listeners are called within a useEffect hook just like that: (useEffect with empty braces at the end makes sure those listeners are called only once and not multiple times.)

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

All of the subscribe functions return the unsubscribe function

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM