MM-20694 Fix race condition when the store has not rehydrated (#3610)

* MM-20694 Fix race condition when the store has not rehydrated

* Making waitForHydration re-usable
This commit is contained in:
Elias Nahum
2019-11-27 12:03:50 -03:00
committed by Miguel Alatzar
parent 80d4119dbe
commit 75e0854411
3 changed files with 33 additions and 23 deletions

View File

@@ -16,6 +16,7 @@ import 'app/init/fetch';
import globalEventHandler from 'app/init/global_event_handler';
import {registerScreens} from 'app/screens';
import store from 'app/store';
import {waitForHydration} from 'app/store/utils';
import EphemeralStore from 'app/store/ephemeral_store';
import telemetry from 'app/telemetry';
import pushNotificationsUtils from 'app/utils/push_notifications';
@@ -54,6 +55,7 @@ const launchApp = async (credentials) => {
]);
if (credentials) {
await waitForHydration(store);
store.dispatch(loadMe());
resetToChannel({skipMetrics: true});
} else {

View File

@@ -40,3 +40,25 @@ export function transformSet(incoming, setTransforms, toStorage = true) {
return state;
}
export function waitForHydration(store, callback) {
let unsubscribeFromStore;
return new Promise((resolve) => {
if (__DEV__) {
// when in DEV mode resetting the app can get into a white screen
resolve();
return;
}
const subscription = () => {
if (store.getState().views.root.hydrationComplete) {
unsubscribeFromStore();
if (callback && typeof callback === 'function') {
callback();
}
resolve();
}
};
unsubscribeFromStore = store.subscribe(subscription);
});
}

View File

@@ -23,6 +23,7 @@ import {getCurrentServerUrl, getAppCredentials} from 'app/init/credentials';
import PushNotifications from 'app/push_notifications';
import {getCurrentLocale} from 'app/selectors/i18n';
import EphemeralStore from 'app/store/ephemeral_store';
import {waitForHydration} from 'app/store/utils';
import {t} from 'app/utils/i18n';
class PushNotificationUtils {
@@ -64,9 +65,6 @@ class PushNotificationUtils {
onPushNotification = async (deviceNotification) => {
const {dispatch, getState} = this.store;
let unsubscribeFromStore = null;
let stopLoadingNotification = false;
const {data, foreground, message, userInteraction} = deviceNotification;
const notification = {
data,
@@ -88,15 +86,9 @@ class PushNotificationUtils {
this.loadFromNotification(notification);
}, 0);
} else {
const waitForHydration = () => {
if (getState().views.root.hydrationComplete && !stopLoadingNotification) {
stopLoadingNotification = true;
unsubscribeFromStore();
this.loadFromNotification(notification);
}
};
unsubscribeFromStore = this.store.subscribe(waitForHydration);
waitForHydration(this.store, () => {
this.loadFromNotification(notification);
});
}
}
}
@@ -164,8 +156,7 @@ class PushNotificationUtils {
};
onRegisterDevice = (data) => {
const {dispatch, getState} = this.store;
let unsubscribeFromStore = null;
const {dispatch} = this.store;
let prefix;
if (Platform.OS === 'ios') {
@@ -180,15 +171,10 @@ class PushNotificationUtils {
EphemeralStore.deviceToken = `${prefix}:${data.token}`;
// TODO: Remove when realm is ready
const waitForHydration = () => {
if (getState().views.root.hydrationComplete && !this.configured) {
this.configured = true;
dispatch(setDeviceToken(EphemeralStore.deviceToken));
unsubscribeFromStore();
}
};
unsubscribeFromStore = this.store.subscribe(waitForHydration);
waitForHydration(this.store, () => {
this.configured = true;
dispatch(setDeviceToken(EphemeralStore.deviceToken));
});
};
getNotification = () => {