React Native iOS realtime events listeners

79 Views Asked by At

I am using react-native-firebase for authentication, Realtime Database and Notifications and I am having a bug with realtime events listeners just on iOS it is working fine on Android.

the issue is happening when I kill the app and restart it, when I first install the app the listeners are working and I am getting the updates but once I restart the app the listeners are not firing for updates anymore. I am suspecting that the cleanup is not working properly when I call off on the reference especially when I kill the app on the screen that is starting the listeners.

I tried calling off on the specific listener, by eventType and on all the listeners on the reference but none of them seems to be working.

I also think that it is good to mention that this bug started after I implemented cloud messaging, it used to work properly before that. I also tested different react-native-firebase versions but the bug is always there.

Tested versions: 18.5.0, 18.4.0, 17.5.0 and 17.4.0.

The following is the hook that I am calling in the posts screen.

export function PostListenerHook(challengeId: number) {
  const dispatch = useAppDispatch();

  useFocusEffect(
    useCallback(() => {
      const now = moment.utc(new Date()).toDate();
      const databaseRef = database().ref(
        `/updates/challenges/${challengeId}/mainposts`,
      );

      const onPostUpdated = databaseRef.on(
        'child_changed',
        snapshot => {
          let updatedPostId = snapshot.key;
          if (updatedPostId !== null) {
            let postRequest: PostRequest = {
              challengeId: challengeId,
              postId: Number(updatedPostId),
            };
            dispatch(checkShouldRefresh(postRequest));
          }
        },
        err => console.log('errror: ', err),
      );

      const onPostAdded = databaseRef.on(
        'child_added',
        snapshot => {
          let updatedDatetimeUTC = snapshot.val()?.UpdatedDatetimeUTC
            ? moment.utc(snapshot.val()?.UpdatedDatetimeUTC).toDate()
            : undefined;

          if (updatedDatetimeUTC && isDateAfter(updatedDatetimeUTC, now)) {
            let updatedPostId = snapshot.key;
            if (updatedPostId) {
              let postRequest: PostRequest = {
                challengeId: challengeId,
                postId: Number(updatedPostId!),
              };
              dispatch(getNewPostByIdThunk(postRequest));
            }
          }
        },
        err => console.log('errror: ', err),
      );

      // Stop listening for updates when no longer required
      return () => {
        console.log('child_changed clenup');
        databaseRef.off('child_changed', onPostUpdated);
        console.log('child_added clenup: ');
        databaseRef.off('child_added', onPostAdded);
        // Also tested by event type
        databaseRef.off('child_changed');
        databaseRef.off('child_added');
        // And also tested to remove all listeners on that reference
        databaseRef.off();
      };
    }, [challengeId, dispatch]),
  );
}
0

There are 0 best solutions below