确认远程同步-带ReactJS + Redux + Saga的Firebase实时数据库

问题描述 投票:1回答:1

我有一个ReactJS / Redux / Saga应用程序,该应用程序当前从Firebase实时数据库发送和读取数据。在发送和接收数据时,会有一个全局redux状态值loading,该值在发送数据和确认数据现在在Firebase中之间在truefalse之间切换。在这种情况下,loading默认为false

当用户更新其数据时,该流当前为:

  • Redux减速器SEND_TO_FIREBASE

return { ...state, loading: true };

  • 此减速器触发Saga函数sendToFirebaseSaga()
     function* syncToFirebaseSaga({ payload: userData }) {
        try {
            var uid = firebase.auth().currentUser.uid;
            const database = (path, payload) => {
                firebase
                    .database()
                    .ref(path)
                    .set(payload);
            };
            yield call(database, "users/" + uid + "/userData", userData);
            yield console.log("successfully written to database");
        } catch (error) {
            alert(error);
        }
    }
  • 所以,在这一点上,loading:true(确认这可行)
  • 然后,作为我的根组件之一的componentDidMount的一部分,我有一个侦听器,用于监听Firebase数据库的更改:
    var props = this.props

    function updateStateData(payload, props) {
        props.syncFirebaseToState(payload);
        }

    function syncWithFirebase(uid, props) {
        var syncStateWithFirebaseListener = firebase.database().ref("users/" + uid + "/userData");
        syncStateWithFirebaseListener.on("value", function(snapshot) {
            var localState = snapshot.val();
            updateStateData(localState, props);
            });
        }

  • [this.props.syncFirebaseToState(payload)是使用该reducer的Redux动作:

return { ...state, data: action.payload, loading: false };

  • 然后确认数据已写入Firebase实时数据库,然后删除加载页面,让用户知道他们的更新现在是安全的。

在大多数情况下,此流程运行正常。但是,当用户的互联网连接不良或刷新页面太快时,我会遇到问题。例如:

  • 用户加载应用程序。
  • 与互联网断开连接。
  • 提交数据。
  • [完整循环立即生效,loading:false(Firebase Realtime数据库以“脱机模式”将其写入,并正在等待重新连接到互联网)
  • 用户在线重新连接。
  • 联机后,用户立即刷新页面(重新加载React应用)
  • Firebase实时数据库没有时间将排队的更新同步到远程数据库,现在刷新页面后,编辑就无法进行。

有时,用户不必失去互联网连接。如果他们提交编辑(页面立即返回“成功读取”),然后在远程服务器将其写下之前刷新,则刷新完成后数据将丢失。

无论如何,正如您所看到的,这是一种非常糟糕的用户体验。在删除加载屏幕之前,我真的需要一种方法来确认数据已实际写入Firebase。我觉得我一定在这里做错了什么,而在没有成功的情况下却获得了成功的回调。

这是我第一次使用React / Redux / Saga / Firebase,非常感谢您的耐心和帮助!

reactjs firebase firebase-realtime-database redux redux-saga
1个回答
0
投票

您可以仅禁用离线模式。

我假设您不想这样做,那么下一步就是添加一个条件来检查您的更新是否来自缓存或数据库。

Firebase Realtime Database在/.info/connected处提供了一个特殊位置,该位置在Firebase Realtime Database客户端的连接状态每次更改时都会更新。这是一个例子:

var connectedRef = firebase.database().ref(".info/connected");
connectedRef.on("value", function(snap) {
  if (snap.val() === true) {
    alert("connected");
  } else {
    alert("not connected");
  }
});

然后,您可以在更新时运行此检查以关闭加载,然后根据更改来自缓存还是实际数据库来传播更改。

© www.soinside.com 2019 - 2024. All rights reserved.