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



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

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

  • Redux reducer 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)是使用此化简器的 Redux 操作:

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

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

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

  • 用户加载应用。
  • 断开与互联网的连接。
  • 提交数据。
  • 完整循环立即工作并loading:false(Firebase 实时数据库将其写入"离线模式",正在等待重新连接到互联网(
  • 用户重新联机连接。
  • 上线后,用户立即刷新页面(重新加载 React 应用程序(
  • Firebase 实时数据库没有时间将排队的更新同步到远程数据库,现在页面刷新后,编辑不会进行。

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

无论如何,正如你所看到的,这是一个非常糟糕的用户体验。在删除加载屏幕之前,我真的需要一种方法来确认数据是否已实际写入Firebase。我觉得我一定在这里做错了什么,并且不知何故得到了成功的回调。

这是我第一次使用 React/Redux/Saga/Firebase,所以我感谢你的耐心和帮助!

您可以禁用离线模式。

我假设您不想这样做,因此接下来是添加一个条件来检查您的更新是来自缓存还是数据库。

Firebase 实时数据库在

/.info/connected 处提供了一个特殊位置,每当 Firebase 实时数据库客户端的连接状态发生变化时,该位置都会更新。下面是一个示例:

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

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

最新更新