我有一个ReactJS / Redux / Saga应用程序,该应用程序当前从Firebase实时数据库发送和读取数据。在发送和接收数据时,会有一个全局redux状态值loading
,该值在发送数据和确认数据现在在Firebase中之间在true
和false
之间切换。在这种情况下,loading
默认为false
。
当用户更新其数据时,该流当前为:
SEND_TO_FIREBASE
return { ...state, loading: true };
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 };
在大多数情况下,此流程运行正常。但是,当用户的互联网连接不良或刷新页面太快时,我会遇到问题。例如:
loading:false
(Firebase Realtime数据库以“脱机模式”将其写入,并正在等待重新连接到互联网)有时,用户不必失去互联网连接。如果他们提交编辑(页面立即返回“成功读取”),然后在远程服务器将其写下之前刷新,则刷新完成后数据将丢失。
无论如何,正如您所看到的,这是一种非常糟糕的用户体验。在删除加载屏幕之前,我真的需要一种方法来确认数据已实际写入Firebase。我觉得我一定在这里做错了什么,而在没有成功的情况下却获得了成功的回调。
这是我第一次使用React / Redux / Saga / Firebase,非常感谢您的耐心和帮助!
您可以仅禁用离线模式。
我假设您不想这样做,那么下一步就是添加一个条件来检查您的更新是否来自缓存或数据库。
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");
}
});
然后,您可以在更新时运行此检查以关闭加载,然后根据更改来自缓存还是实际数据库来传播更改。