This is the context :
When I open my app I'm querying my firebase database. These queries are async, I'm waiting for firebase to give me the answer and then I return the value in redux. I'm using redux-persist so when redux get the response of firebase, redux-persist write the data on my phone.
This is the problem :
The problem is that if the user leave the app and then reopen it, if firebase return the response while the app is in background, redux-persist will try to write with AsynStorage. iOS doesn't allow this so my app will crash with these 2 errors
Error storing data for key: "profile"
'Failed to symbolicate warning, "%s":', 'Possible Unhandled Promise
Rejection (id: 0):
Failed to write manifest file.Error Domain=NSCocoaErrorDomain
Code=513 "You don’t have permission to save
the file “manifest.json” in the folder “RCTAsyncLocalStorage_V1”."
UserInfo=
{NSFilePath=/var/mobile/Containers/Data/Application/
C892F501-5057-4FE4-A622-2037C32D1373/Documents/
RCTAsyncLocalStorage_V1/manifest.json,
NSUserStringVariant=Folder, NSUnderlyingError=0x17025b810 {Error
Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}'
What I tried :
I have tested two solutions :
First Try I have tried to pause the persistor of redux-persist depending on the app state.
Store.js
export const persistor = persistStore(store, { storage: AsyncStorage }, () => {
console.log('restored');
});
And then in my Home component
componentDidMount() {
if (Platform.OS === 'ios') {
AppState.addEventListener('change', this.handleAppStateChange);
}
handleAppStateChange = (appState) => {
if (appState !== 'active') {
persistor.pause();
} else {
persistor.resume()
}
};
componentWillUnmount() {
if (Platform.OS === 'ios') {
AppState.removeEventListener('change', this.handleAppStateChange);
}
}
Result Same Error as before, when I tried to console log the current state of the persistor he was paused and resumed on time.
Second Try I have tried to use a CustomAsyncStorage instead of AsyncStore in the persitStore(), I took all the code from AsyncStorage.js and then I add on every method a verification of the current app State who return the method if app state isn't active.
Result No luck redux-persist and redux stop working.
My Other ideas
Cancel every call of firebase when the app pass in background -> Can't be done no Method exist for that
In each method where I call Firebase and dispatching value in redux, check the current state of the app and return it only if app is active -> That means I should check every call so it's a lot of repetition.
React-native Version: 0.39.2
Redux-persist Version: 4.4.2
I'm open of any idea or any help for this case, what do you think I should do for resolve this issue? And which is the best
Thanks.
答案 0 :(得分:1)
检查iOS应用程序的权利是否已启用数据保护。它可能配置为NSFileProtectionComplete
。
如果启用此类数据保护,默认情况下会对所有文件进行加密。这包括存储支持React Native的AsyncStorage。当应用程序位于前台时,这不是问题,但是,在应用程序背景或锁定设备后不久,iOS将丢弃您的解密密钥。
如果您的应用在卸载解密密钥后尝试写入文件(例如通过AsyncStorage),则文件操作将失败,并且您看到的信息正常无用(<无效):
Error Domain=NSCocoaErrorDomain Code=513 "You don’t have permission to save the file ...
一个简单的解决方法是将您的默认数据保护级别更改为NSFileProtectionCompleteUntilFirstUserAuthentication
。有关详细信息,请参阅本指南中的“加密和数据保护”:https://www.apple.com/business/docs/iOS_Security_Guide.pdf