Home > other >  Firebase Realtime Database concurrent connections reliability
Firebase Realtime Database concurrent connections reliability

Time:01-11

I count the concurrent connections as follows:

onValue(ref(db, '.info/connected'), snapshot => {
            
    if (snapshot.val()) {

        let con = push(ref(db, 'concurrent'), { connected: moment().format('DD/MM/YYYY HH:mm') })

        onDisconnect(con).remove()

    }
}) 

However, when I check the database, I see connections from several days ago:

enter image description here

Does that mean that users have had inactive browser tabs since several days ago? Am I doing something wrong? Is the onDisconnect() function 100% reliable?

CodePudding user response:

firebaser here

Do you have security rules on the concurrent path that require the user to be authenticated by any chance? Because there's an open issue around that, which has been causing problems for more people recently.

Aside from that we haven't seen reliability issues in onDisconnect handling recently, so we'd need to see more information about the lingering connections (a stand-alone repro would be good).

CodePudding user response:

Reading the issue, it seems that if the tab is inactive for more than an hour, the token expires. If the tab is active again, Firebase client reconnects and gets a new token.

To remove the path in case of token expiration (idle tab):

const removeOnIdleTab = (key, ms) => {

    var timer

    document.addEventListener('visibilitychange', () => {

        if(document.hidden){

            // If tab is inactive, delete the path after 'n' ms
            timer = setTimeout(() => remove(ref(db, `concurrent/${key}`)), ms)

        }
        else{

            // If tab is active again, clear the timer
            clearTimeout(timer)

            // If tab is active after 60 mins, rebuild the path. 
            // Otherwise, don't do anything (returning undefined cancels the transaction)
            runTransaction(ref(db, `concurrent/${key}`), value => {
                
                return value ? undefined : ({ connected: moment().format('DD/MM/YYYY HH:mm') })
                
            })

        }

    })

}

Finally:

onValue(ref(db, '.info/connected'), snapshot => {
    
    if (snapshot.val()) {

        let con = push(ref(db, 'concurrent'), { connected: moment().format('DD/MM/YYYY HH:mm') })

        onDisconnect(con).remove()

        removeOnIdleTab(con.key, 60 * 60 * 1000)

    }
}) 
  •  Tags:  
  • Related