Closed vaukalak closed 2 years ago
you can try using a custom storage. I haven't tested it in react-native yet, but you can take a look at this: https://github.com/antoniopresto/react-native-local-mongodb/blob/7147ea9a5a02577b455ee3aa52a0927858256d6a/lib/datastore.js#L42
the mock used to test in jest is an example of custom storage: https://github.com/antoniopresto/react-native-local-mongodb/blob/master/config/AsyncStorageMock.js
Hi @vaukalak , @antoniopresto , needed to change my storage because of android limitations and finally had the time to test this. Works like a charm! Used expo FilesSystem API because I'm on ExpoKit, but I could also have used something like rn-fetch-blob
to the same effect (redux-persist-filesystem-storage does exactly that).
Here's my code, for completeness:
import {FileSystem} from 'expo'
let options = {
storagePath: `${FileSystem.documentDirectory}database`,
toFileName: (name) => name.split(':').join('-'),
fromFileName: (name) => name.split('-').join(':'),
};
// init directory: make sure our database path exists on startup
FileSystem.getInfoAsync(options.storagePath)
.then(async ({exists}) => {
return !exists && await FileSystem.makeDirectoryAsync(options.storagePath);
}).catch(e => {
console.warn('Error creating database path',e);
});
const pathForKey = (key) => `${options.storagePath}/${options.toFileName(key)}`;
const FilesystemStorage = {
config: (customOptions) => {
options = {
...options,
...customOptions,
}
},
setItem: (key, value, callback) =>
FileSystem.writeAsStringAsync(pathForKey(key), value)
.then(() => callback && callback())
.catch(error => callback && callback(error)),
getItem: (key, callback) =>
FileSystem.readAsStringAsync(pathForKey(options.toFileName(key)))
.then(data => {
callback && callback(null, data);
if (!callback) {
return data
}
})
.catch(error => {
callback && callback(error);
if (!callback) {
throw error
}
}),
removeItem: (key, callback) =>
FileSystem.deleteAsync(pathForKey(options.toFileName(key)))
.then(() => callback && callback())
.catch(error => {
callback && callback(error);
if (!callback) {
throw error
}
}),
getAllKeys: (callback) =>
FileSystem.getInfoAsync(options.storagePath)
.then(async ({exists}) =>
exists ? true : await FileSystem.makeDirectoryAsync(options.storagePath)
)
.then(() =>
FileSystem.readDirectoryAsync(options.storagePath)
.then(files => files.map(file => options.fromFileName(file)))
.then(files => {
callback && callback(null, files);
if (!callback) {
return files
}
})
)
.catch(error => {
callback && callback(error);
if (!callback) {
throw error
}
}),
};
FilesystemStorage.clear = (callback) =>
FilesystemStorage.getAllKeys((error, keys) => {
if (error) {
throw error;
}
if (Array.isArray(keys) && keys.length) {
const removedKeys = [];
keys.forEach(key => {
FilesystemStorage.removeItem(key, error => {
removedKeys.push(key);
if (error && callback) {
callback(error, false);
}
if (removedKeys.length === keys.length && callback) {
callback(null, true);
}
})
});
return true
}
callback && callback(null, false);
return false
}).catch(error => {
callback && callback(error);
if (!callback) {
throw error
}
});
export default FilesystemStorage
Later, when initialising the database:
import DataStore from 'react-native-local-mongodb';
import FilesystemStorage from './FilesystemStorage';
export const Visits = async () => {
const db = new DataStore({filename: 'db.visits',storage: FilesystemStorage});
await db.loadDatabaseAsync();
db.ensureIndex({fieldName: 'companyId'});
db.ensureIndex({fieldName: 'date'});
db.ensureIndex({fieldName: 'driverId'});
db.ensureIndex({fieldName: 'priority'});
db.ensureIndex({fieldName: 'closed'});
db.ensureIndex({fieldName: 'inProgress'});
db.ensureIndex({fieldName: 'skipped'});
return db
};
(...)
try react-native-nedb, it store to file
@joaopiopedreira Is it possible to encrypt the storage file?
Hi @joaopiopedreira
How to use Custom Storage in React Native CLI for local Mongo DB since you have used Expo over here
@emannick do you think it is possible to encrypt the file ?
@BenoitClaveau we should ask this to @joaopiopedreira. Since he has tried with the Expo.
If you need that, just use a custom storage. or send a PR. https://github.com/antoniopresto/react-native-local-mongodb/issues/42#issuecomment-418715160
My app needs an offline mode, which operates ~60MB of data. And this causes 2 issues: 1 - on android the app AsyncStorage by default limits to 6MB (this can be avoided). 2 - considering indexes, that also use some memory, this will generate a big impact on RAM usage, and may lead to app crashes especially on android.
So my question is: do you have any plans to support file storage, if yes, how can I help you with that? Thanks.