Основная цель: правильно отписаться от всех firestore-listeners перед выходом пользователя из системы, чтобы предотвратить утечки.

Участвующие библиотеки: react, react-native, redux, redux-thunk и react-native-firebase.

Проблема: Отказаться от подписки на firestore (...). OnSnapshot () не работает при использовании dispatch ().

Я получаю данные с помощью onSnapshot и возвращаю функцию отмены подписки вызывающему компоненту, который вызываю при выходе пользователя из системы. Как ни странно, UNSUBSCRIBE работает только тогда, когда не отправляется диспетчеризация ...

У меня есть компонент (component.js), который подключен к хранилищу redux и постоянно извлекает некоторые пользовательские данные, например:

componentDidMount() {
  this.unsubscribe = this.props.userFetch(); // userFetch is an action creator in actions.js
}

В actions.js

import firestore from '@react-native-firebase/firestore';
import auth from '@react-native-firebase/auth';

export const userFetch = () => {
  return dispatch => {
    const unsubscribe = firestore()
      .doc(`users/${auth().currentUser.uid}`)
      .onSnapshot({
        error: e => console.warn('ERROR IN FETCH: ', e),
        next: SnapshotUser => {
          console.log('User: ', SnapshotUser.data());
          // Will dispatch action below
        },
      });
    return unsubscribe;
  };
};

Обратите внимание, что на данный момент в создателе предыдущего действия нет DISPATCH.

Если я вызываю unsubscribe в component.js, прослушиватель onSnapshot firestore отписывается правильно, например:

onLogoutPressed = () => {
  this.unsubscribe(); // <-- HERE it works (for the moment...)
  auth()
    .signOut()
    .then(() => {
      console.log('user has been signout');
    })
    .catch(error => {
      console.log('Error: ',error);
    });
};

Теперь, если я хочу отправить полученные данные в хранилище redux с отправкой, я добавляю отправку, подобную этой, в actions.js

export const userFetch = () => {
  return dispatch => {
    const unsubscribe = firestore()
      .doc(`users/${auth().currentUser.uid}`)
      .onSnapshot({
        error: e => console.warn('ERROR IN FETCH: ', e),
        next: SnapshotUser => {
          console.log('User: ', SnapshotUser.data());
          // Will dispatch action below
          dispatch({   // <--------------------------------- HERE
            type: 'USER_FETCH_SUCCESS',
            payload: SnapshotUser.data(),
          });
        },
      });
    return unsubscribe;
  };
};

Но затем внезапно в моем component.js this.unsubscribe больше не работает при выходе из системы.

Я обнаружил, что этот парень делает то же самое, но работает на него на React: здесь. Решение, предоставленное этим другим парнем, в основном тоже то же самое .

Похоже, что firestore-onsnapshot-listener обернут каким-то диспетчерским вызовом из-за redux-thunk, и я не могу понять, как он сейчас себя ведет.

Есть ли у кого-нибудь решение?

0
JimA 15 Апр 2020 в 02:06

1 ответ

Лучший ответ

Хорошо, решил это с помощью @ioss на Reactiflux. ComponentDidMount монтировался дважды по каким-то странным причинам, создавая несколько слушателей, поэтому размонтирования одного было недостаточно. Решил это, добавив еще один запуск функции unsubscribe () в componentWillUnmount ().

0
JimA 16 Апр 2020 в 00:40