【问题标题】:correct way to use firestore onSnapShot with react redux将firestore onSnapShot与react redux一起使用的正确方法
【发布时间】:2018-09-18 21:03:51
【问题描述】:

我正在尝试找出将 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()?我是否从.checkin() 动作创建者那里调用.fetchCheckins()?我如何根据最佳实践进行处理?谢谢

【问题讨论】:

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


    【解决方案1】:

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

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

    附:结帐 redux-firestore:https://github.com/prescottprue/redux-firestore - 这是一个很好的库,可以帮助您进行 redux 绑定。

    【讨论】:

    • 有没有关于如何使用redux-firestore的好例子,我的状态对象中出现了firestore,但我不确定如何获取集合
    【解决方案2】:

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

    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 接收到一个 emmiter,该 emmiter 会生成一个 saga 效果以与 take 一起使用。 eventChannel 必须返回一个函数来关闭连接,但是 afaik .onSnapshot 连接不需要显式关闭,这就是我返回一个虚拟函数的原因。

    【讨论】:

    • 您确定不需要关闭连接吗? @FrankvanPuffelen 表示他们 need to be
    猜你喜欢
    • 1970-01-01
    • 2020-02-08
    • 2017-07-29
    • 1970-01-01
    • 2020-05-13
    • 2019-05-20
    • 2019-02-05
    • 2017-12-09
    • 2018-12-05
    相关资源
    最近更新 更多