React-native-firebase: [Android] 'child_added' fired multiple times when going all the way to homescreen with back button

Created on 16 Nov 2017  路  6Comments  路  Source: invertase/react-native-firebase

How to reproduce:

  1. Create a 'child_added' listener to a ref upon app start, in my case it is the main constructor
  2. Add data to that ref
  3. Go back to homescreen, re-open the app
  4. Add data to the same ref, the callback fires two times
  5. If I go again from step 3, the callback fires three times

As I can understand, the child_added callback is not garbage collected when going back, but app starts from scratch and a new one is set up each time.

Any hints? Thanks

  1. macOS Sierra 10.12.6
  2. React Native 0.49.3
  3. React Navigation 1.0.0-beta.14
  4. RNFirebase 3.0.3
  5. Firebase modules: Auth, Storage, Messaging, Realtime Database
  6. Node 8.7.0

@Ehesp

Android Database Waiting for User Response

Most helpful comment

Please fill out the issue template.

All 6 comments

Please fill out the issue template.

This happens on 4 different phones with a release apk as well as the emulator, so I don't think it's a problem of the environment.

Hmm could you share some code on how you have it setup so we can try and replicate please?

I'm dispatching _startMainRoomsListener() in componentDidMount

function _startRoomListener (roomID) {
    return async (dispatch, getState) => {
        const { Auth } = getState()

        let lastReadTime = JSON.parse(await AsyncStorage.getItem('@CHAT_LAST_SYNC-' + roomID))
        dispatch({
            type: 'LAST_READ_TIME_READ',
            data: lastReadTime,
            roomID: roomID
        })

        let ref = firebase.database().ref('messages/' + roomID)
        ref.keepSynced(true)
        ref.on('child_added', (snap) => {
            message = snap.val()

            dispatch({
                type: 'NEW_MESSAGE',
                roomID: roomID,
                isFromSelf: (message.fromMerchant && Auth.isMerchant) || (!message.fromMerchant && !Auth.isMerchant),
                data: message
            })
        })
    }
}

export function _startMainRoomsListener () {
    return async (dispatch, getState) => {
        dispatch({
            type: 'START_FETCHING_ROOMS'
        })

        const {聽Auth } = getState()
        const key = Auth.isMerchant ? "merchantID" : "buyerID"
        let ref = firebase.database().ref('chatrooms')
        ref.keepSynced(true)

        ref.orderByChild(key).equalTo(Auth.id).on('child_added', (snap) => {
            data = snap.val()

            dispatch({
                type: 'ROOM_ADDED',
                data: {
                    ... data,
                    unreadCount: 0,
                    id: snap.key
                }
            })

           dispatch(_startRoomListener(snap.key))
        })
    }
}

@DavideValdo doesn't look like you're calling .off() anywhere to unsubscribe from the child_added events on teardown, I'd also confirm _startMainRoomsListener is not being called multiple times - add a console log and navigate as you mentioned in the issue.

React lifecycle events are triggered when app is started from the icon after hiding it through the back button, but not on a background/foreground state change. The problem was having _startMainRoomsListener() in the componentDidMount()method of the chat list component.

Was this page helpful?
0 / 5 - 0 ratings