expo.sqlite high memory usage when creating to many transactions at a close interval - react-native

I am using expo-sqlite for my application and encounter an odd problem.
I have a ``ScrollViewand I want to save the scroll position too the db and so I am doing it inonScrollEndDrag`
The issue is that as time gets by say 3 to 4 hours, I see a memory increase in the app Info.
it goes to 1GB+ sometimes. Is that normal?
I am using expo-sqlite-wrapper Which I do not believe that the issue originate from there.
You can look at its code here as I am the author of the library, I could make change and fix it if there is an issue.
Here is the code for save operation, it really as simple as savechange() and Save() operation in the link above.
onScrollBeginDrag={() => {
clearTimeout(onScrollTimeout.current);
scrollable.current = true;
}}
onScrollEndDrag={({ nativeEvent }) => {
clearTimeout(onScrollTimeout.current);
onScrollTimeout.current = setTimeout(() => {
scrollable.current = false;
if (nContext.state.currentChapterSettings && nContext.state.currentChapterSettings.savechanges && !nContext.state.viewPlayer)
nContext.state.currentChapterSettings.savechanges();
}, 1500);
if (!nContext.state.viewPlayer)
setContentOffset(nativeEvent.contentOffset);
}}
onScroll={({ nativeEvent }) => {
if (!nContext.state.viewPlayer && scrollable.current) {
onScroll(nativeEvent);
}
}}
Is it maybe accessing the database to often is wrong or is it really alright as the sqlite takes care of the memory issue when its full?
Could anyone please explained how SQLite really handle the memory, as I may not understanding this right and this behavior is really alright.

Related

Why does Parse LiveQuery not always trigger update/create/enter event?

I am trying to achieve a board that enables real-time editing for cooperating users. I am running a parse server using Sashido, where I have LiveQueries enabled for among other things 'Sticky'. For the frontend I have the following code:
const query = new Parse.Query(Sticky);
... some query constraints
this.subscription = await query.subscribe();
this.subscription.on('open', () => {
console.log('SUBSCRIPTION: opened');
}
this.subscription.on('create', (sticky) => {
console.log('SUBSCRIPTION: created');
}
this.subscription.on('update', (sticky) => {
console.log('SUBSCRIPTION: updated');
}
this.subscription.on('enter', (sticky) => {
console.log('SUBSCRIPTION: entered');
}
this.stickies = await query.find();
When I open my application in two different browser tabs, I get the 'SUBSCRIPTION: opened'. When I edit or create Sticky instances, I expect to get the corresponding events and see changes in the Sashido database.
However, I always see the changes in the database, but half of the times when I create or edit Sticky instances, I do not get the update/create/enter events. Note: Sometimes they do get triggered, but I have not found a sequence of events that leads to them being triggered or not, it seems to happen at random.
Can someone see what I'm doing wrong?

DatePicker is working really weird in iOS react-native 0.60.6

Don't know when this happened because it used to work before, but it might be probably ever since I upgraded react-native to 0.60.6.
I tested 3 libraries thus far, and it's happening in all of them. Currently using react-native-woodpicker.
This is how it looks, it's all messed up:
Even though it shows no value where i'm standing at, there really is, you can literally feel the vibration when swiping up/down, but most of the times there is no value, you can swipe for like 10 seconds straight and all of a sudden the list of values will show up.
It's happening in all the DatePickers within my app, and only in iOS, Android works fine. So there seems to be an issue with DatePickerIOS.
Some code:
<DatePicker
onDateChange={this.handleDatePicker}
date={new Date(this.state.user.dateOfBirth)}
title={i18n.t('dateOfBirth')}
placeholder={this.handleDatePickerPlaceholder()}
placeholderStyle={scopedStyles.datePickerText}
iosPickerMode="date"
androidPickerMode="spinner"
minDate={minDate}
maxDate={new Date()}
/>
handleDatePicker = data => {
var {user} = this.state;
var thisUser = user;
var date = this.getObjectFromDate(data);
thisUser.dateOfBirth = data;
this.setState({
user: thisUser,
dateObject: date
});
};
getObjectFromDate(date) {
return {
day: date.getDate(),
month: (date.getMonth()) + 1,
year: date.getFullYear()
}
};
handleDatePickerPlaceholder() {
const {dateObject} = this.state;
if (Object.keys(dateObject).length) {
return `${dateObject.day}/${dateObject.month}/${dateObject.year}`
} else {
return `DD/MM/YYYY`;
}
}
Any help given is appreciated.
If anyone is under the same problem, it's due to iOS 13's dark mode, thanks to this guy on github, I was able to solve it.
The way to solve it is to add a new key/string value within info.plist file in your iOS app.
<key>UIUserInterfaceStyle</key>
<string>Light</string>
Hope this helps to others.

React-native sound delay issue

This is just general question. I want to make drums-like app but i have sound delay. Maybe someone tried some other package(s) and did some magic, I used react-native-sound and react-native-video since they are most popular and not outdated like others. This is code sample:
new Sound(`${filename}.mp3`, Sound.MAIN_BUNDLE, error => {
if (error) {
return;
} else {
audio.play(() => {
audio.release();
});
}
});
There are other libraries, maybe outdated, but i am looking for any input to make it better, we did handler with onPressIn to make it slightly faster but still big delay:
<TouchableOpacity onPressIn={handleOpenPress}>
If this fails I will try to make another library, but I fear it will have the same delay. For some reason this repo works very fast: https://github.com/dwicao/react-native-drum-kit. I used same code and made even a list with prepared sounds to be used like soundList[i++ % 10].play() but still no effect.

Is it possible to remove all items from AsyncStorage

I'm testing my React-Native application and want to remove all items from AsyncStorage in order to test the app from the beginning. And I am a bit confused.
I read the official documentation and found multiRemove and clear functions, but I cannot understand how to clear all items of my application (clear as far as I understood clear the whole storage of all applications and I'm afraid to use it),
and multiRemove delete only keys that I give it in parameters, but I want to clear all keys.
I suppose I can do it through getAllKeys keys-values and remove it one-by-one, but maybe there is a more clear way to do it? :)
thanks
P.S: I tried to to like this:
clearAllData() {
AsyncStorage.multiRemove([]).then(() => alert('success'));
}
but it doesn't work...
I suppose I can do it through getAllKeys keys-values and remove it one-by-one, but maybe there is a more clear way to do it? :)
You should do that, that's the only way to remove all keys from your app.
Here is a simple way of doing it:
clearAllData() {
AsyncStorage.getAllKeys()
.then(keys => AsyncStorage.multiRemove(keys))
.then(() => alert('success'));
}
When your app runs, it is assigned a unique ID. Each stored key is prefixed by the ID. Therefore, all YOUR app's keys can be identified.
Using AsyncStorage.clear does not use unique identifiers and will delete keys for all clients, apps, and libraries. This might be OK in development but probably undesirable in production.
Per #Bruno Soares, multiRemove is preferred. However, note that 'await' can only be used within an async function. Combining Bruno's answer with #Prawesh Panthi, the following function will delete keys that are only associated with your app without having to explicitly identify the keys.
removeAppKeys = async () => {
let keys = []
try {
keys = await AsyncStorage.getAllKeys()
console.log(`Keys: ${keys}`) // Just to see what's going on
await AsyncStorage.multiRemove(keys)
} catch(e) {
console.log(e)
}
console.log('Done')
}
removeFew = async () => {
const keys = ['#MyApp_USER_1', '#MyApp_USER_2']
try {
await AsyncStorage.multiRemove(keys)
} catch(e) {
// remove error
}
console.log('Done')
}
Here a way of doing it, using async/await:
const keys = await AsyncStorage.getAllKeys()
await AsyncStorage.multiRemove(keys)

How to throttle background task based on InteractionManager?

I have a list of projects in a Redux store. When new location data arrives from the GPS I'm updating the distance to each project in the list. Currently I'm throttling the update to 5 second intervals.
If the update coincides exactly with a navigation transition (using Ex-navigation) I get a non-smooth transition.
I would like to throttle based on a time interval and on data from InteractionManager.
Here is the current code:
let throttledProjectUpdate = _.throttle((position) => {
dispatch(ProjectState.projectNewLongLat(position.coords.longitude, position.coords.latitude))
}, 5000)
let watchId = navigator.geolocation.watchPosition((position) => {
dispatch(sensorGeoNewPositionAction(position))
throttledProjectUpdate(position)
});
I would like to do something like this:
let throttledProjectUpdate = _.throttle((position) => {
InteractionManager.runAfterInteractions(() =>
dispatch(ProjectState.projectNewLongLat(position.coords.longitude, position.coords.latitude))
);
}, 5000)
let watchId = navigator.geolocation.watchPosition((position) => {
dispatch(sensorGeoNewPositionAction(position))
throttledProjectUpdate(position)
});
But a few things are stopping me:
Is this really possible? I.e is InteractionManager a singleton which I can require from everywhere?
It feels wrong to mix GUI stuff with my background state updating
How should I solved this?