正确的方法来使用firestore onSnapShot with react redux

时间:2018-04-09 12:48:40

标签: firebase react-native react-redux google-cloud-firestore redux-thunk

我正试图弄清楚使用firestore.onSnapshot和react-redux的正确方法。

我目前在我的操作文件中有此代码,我在我的组件中调用了componentWillMount()

export const fetchCheckins = () => async (dispatch) => {
const {currentUser} = firebaseService.auth();
try {
    let timestamp = (new Date());

    //set timestamp for beginning of today
    timestamp.setHours(0);
    //get checkins today
    let checkinstoday = (await firebaseService.firestore().collection(`/checkins/${currentUser.uid}/log`).where("timestamp",">=",timestamp).orderBy("timestamp","desc").get()).docs.map(doc => doc.data());
    //set timestamp for beggining of week
    timestamp.setDate(-(timestamp.getDay()));
    //get checkins (week)
    let checkinsweek = (await firebaseService.firestore().collection(`/checkins/${currentUser.uid}/log`).where("timestamp",">=",timestamp).orderBy("timestamp","desc").get()).docs.map(doc => doc.data());
    //set timestamp for begging of month
    timestamp.setDate(0);
    //get checkins (month)
    let checkinsmonth = (await firebaseService.firestore().collection(`/checkins/${currentUser.uid}/log`).where("timestamp",">=",timestamp).orderBy("timestamp","desc").get()).docs.map(doc => doc.data()); 

    dispatch({type: FETCH_CHECKINS, payload: { today: checkinstoday, week: checkinsweek, month: checkinsmonth}});
}
catch(e){
  console.error(e);
}

};

这样可以正常工作,将正确的数据发送到组件并显示。问题是,如果用户签入,则签入数据应该调整,但不会,因为我获取数据并发送一次,状态不会重新呈现。

我的问题是我应该如何处理这个问题?我使用.onSnapshot()代替.get()吗?我是否从.fetchCheckins()动作创建者处拨打.checkin()?我如何按照最佳实践进行操作?谢谢

2 个答案:

答案 0 :(得分:3)

根据firestore的文档,如果您需要实时更新,您应该使用onSnapshot: https://firebase.google.com/docs/firestore/query-data/listen

在您的情况下,如果您使用.get() - 您将获得一次更新,如果任何数据发生更改,firestore将不会通知您。这就是你没有看到变化的原因。

P.S。 checkout redux-firestore:https://github.com/prescottprue/redux-firestore - 这是一个很好的库,可以帮助你进行redux绑定。

答案 1 :(得分:1)

您可以像这样订阅您的列表:

function subscribeToExperiences() {
  return eventChannel((emmiter: any) => {
    experiencesRef.onSnapshot({ includeMetadataChanges: true }, snapshot => {
      const experiences: IExperience[] = snapshot.docChanges().map(change => ({
        id: change.doc.id,
        title: change.doc.data().title
      }));

      if (snapshot.docChanges().length !== 0) {
        emmiter(experiences);
      }
    });

    return () => experiencesRef;
  });
}

function* fetchExperiences(_: ExperiencesFetchRequested) {
  const channel = yield call(subscribeToExperiences);
  try {
    while (true) {
      const experiences = yield take(channel);
      yield put(new ExperiencesFetchSucceeded(experiences));
    }
  } finally {
    if (yield cancelled()) {
      channel.close();
    }
  }
}

subscribeToExperiences使用redux-saga eventChanneleventChannel接收到一个发射器,该发射器产生传奇效果,并与take一起使用。 eventChannel必须返回一个函数以关闭连接,但是afaik .onSnapshot连接不需要显式关闭,这就是为什么我返回一个伪函数的原因。