iOS error while trying to write fetched database data using AsyncStorage when App is in Background

时间:2017-08-04 13:16:36

标签: javascript ios firebase react-native redux

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.

1 个答案:

答案 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

相关问题