Why is React Native AsyncStorage so slow on my phone? - react-native

I have a problem with an App im Developping with Expo - React Native. The problem is that, having only one small value stored in AsyncStorage, its takes around 25 seconds to load. There are the details:
Expo: Version 33
Ract Native (comes with Expo): 0.59.8
My stored values: {keyOne: "ValueOne"}
This is only an example for testing, obviously in the actual app i have more values. The code i am using for testing, inside App.js is:
async componentDidMount(){
console.log("Storing value...");
await AsyncStorage.setItem("keyOne", "valueOne");
console.log("Value stored");
var value1 = await AsyncStorage.getItem("keyOne");
console.log("Obtained value: "+value1);
}
With this code, the 25 seconds are spend storing the item.
I'm facing this problem specifically in Samsung Phones, for example a Galaxy S7 SM-g930F. This happens when developing and in production app.
Also, if I store more values, the first that i obtain is the one slow, the rest are very fast.
Another detail is that, if i make the same test with SecureStore, is very fast.
Can i do something to speed things up?
Some alternative to AsyncStorage?

Make sure to do following.
Upgrade react-native version to 0.59.5 +
Don't import {AsyncStorage} from react-native (as it is deprecated now)
Use this package instead Async Storage
Import like this import AsyncStorage from '#react-native-community/async-storage';

Related

Uber H3 geoToH3 is not working in React Native

I am developing simple grid location based application in React Native using Uber H3. I installed H3 by
npm install h3-js. Then
I created a file to read H3Index from latitude and longitude.
import {geoToH3} from 'h3-js';
const getH3Index = () => {
const result = geoToH3(37.3615593, -122.0553238, 7);
console.log(result);
};
When I start to run my React Native application, app hangs on white screen(splash screen) and blocks the whole application. If I comment these lines, app works fine. If uncomment this line, both iOS and Android app is not working.
Any help would be much appreciated!
Please see https://github.com/uber/h3-js/issues/35
This is likely due to a document is not defined error. See the issue thread for several possible workarounds, including this fork which is intended for React Native.

Why does styled-components 5.x warn about "Expected style to contain units."

When styling a React Native app with Styled Components 5.x I'm getting the warning...
Expected style "borderWidth: 2" to contain units.
This didn't happen with previous versions.
What does the warning mean?
After some research and questions on github I tracked this one down...
Styled Components uses the package css-to-react-native for it's React Native conversions.
css-to-react-native recently released version 3 which now requires units to be present for all measurements. Details here.
You should use px for React Native as it is density independent.
I think that using px is a bit of a pain, unintuitive, misleading, and even dangerous if you are using a theme giving some ...px string value to a component (Ionicons size for instance) that expect react native number units.
My way of dealing with this:
import { LogBox } from 'react-native'
LogBox.ignoreLogs([`to contain units`])

Not getting exact latitude longitude on ios device using watchPosition

Issue Description::
I am working on react native tracking application. Basically users check in from a certain place and they need to reach at the destination. Using this application we are finding out the path they are following. I need to get a geocodes from users check in location to destination to track the path he is following.
Now it builds a clean path in case of Android device, but having an issue with ios. For ios it takes a huge variation inside code.
I have tested this by traveling to same place using both devices(ios and android). For Android it's generates a exact latitude longitude values, but for ios there is a huge variation. Why this is happening. I have followed the official doc of react native for geolocation setup.
You can check this link:: https://facebook.github.io/react-native/docs/geolocation.html#ios
We are using react native geolocation service package, GitHub link
This is happening when I have updated react native version to 0.58
Code::
this.watchId = Geolocation.watchPosition((response) => {
this.currentWatchLocationTimeout = this.currentWatchLocationTimeout + WATCH_LOCATION_TIMEOUT;
currentPosition.lat = this.convertToDecimalPoints(response.coords.latitude);
currentPosition.lng = this.convertToDecimalPoints(response.coords.longitude);
//... additional code
}, (error) => {
this.onGeolocationErrorOccurCallback(error);
}, {
enableHighAccuracy: true,
distanceFilter: 5,
showLocationDialog: true
});
Additional Information ::
React Native: 0.58
react-native-geolocation-service: 2.0.0
platform: ios(only)
Best solution that works for me is changes inside react native geolocation files. You need to replace some lines of code. Go inside react native package,
react-native/Libraries/Geolocation/RCTLocationObserver.m
Then replace this line::
#define RCT_DEFAULT_LOCATION_ACCURACY kCLLocationAccuracyHundredMeters
with this::
#define RCT_DEFAULT_LOCATION_ACCURACY 0.0
After this replace this line::
.accuracy = [RCTConvert BOOL:options[#"enableHighAccuracy"]] ? kCLLocationAccuracyBest : RCT_DEFAULT_LOCATION_ACCURACY,
with this one::
.accuracy = RCT_DEFAULT_LOCATION_ACCURACY,
You need to directly search for these lines on above mentioned path.
I found this inside git commits, you can also check this link:: link

When I touch with three fingers error is thrown in react native app

I have developed one app in react native and ready to publish , but at the end while testing when I touch app with three fingers it is giving error which does not look to user, I am not able to solve it.
Well there is a temporary fix which worked for me
import {NativeModules} from 'react-native';
NativeModules.ExceptionsManager = null;

Advantages of having index.ios.js instead of just index.js

New to react-native and used create-react-native-app to make the scaffolding for my first app. It made an App.js which I guess is equivalent to most app's index.js and serves as the entry point to my app.
Looking at a lot of tutorials I'm seeing separate index.ios.js and index.android.js files. I'm confused as to why these apps have seperate files for each platform.
I see from this question that there are even hybrid apps that use both the individual files as well as one index.js.
All these different options are kind of confusing me. What situations would call for using separate files vs just having one entry point?
All these different options are kind of confusing me. What situations would call for using separate files vs just having one entry point?
So far, I've not found a need to have different entry files index.ios.js and index.android.js. The first thing I do, and what most people seem to do, is add something like the following to both files.
import { AppRegistry } from 'react-native'
import App from './App/Containers/App'
AppRegistry.registerComponent('YourAppName', () => App)
You could also delete them both, replacing them with a single index.js file and the above code as well. Not sure why more people (including myself) don't do that.
I think you can safely follow this pattern as well until you find that you need to split your logic between the platforms. Even when you do, I think it's unlikely you'd ever split it from the entry file itself. It's more likely you'll need to split logic further down in your leaf nodes.
When you do need to write platform specific code, you can do so inline using the Platform module.
import { Platform, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
height: (Platform.OS === 'ios') ? 200 : 100,
});
Or Platform.select
import { Platform, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: 'red',
},
android: {
backgroundColor: 'blue',
},
}),
},
});
which you can also use to select the proper component...
const Component = Platform.select({
ios: () => require('ComponentIOS'),
android: () => require('ComponentAndroid'),
})();
<Component />;
The last example could be accomplished via file naming convention as well. For instance, if you have the following two component files...
|- Component.ios.js
|- Component.android.js
and in your file you just require Component as such...
import Component from './Component';
And the bundler will import the proper component based on the .ios or .android bit.
The whole idea of having iOS and android files is for dealing with codes that needs to be written differently in android and iOS. For example, the Picker component in React Native works differently in iOS and Android. By splitting the code, you can easily split the code and maintain them. When running, React Native will find which file to use automatically based on the platform the app is running on.
Source: https://facebook.github.io/react-native/releases/0.26/docs/platform-specific-code.html
Some components are not universal between ios and Android.
In terms of getting set up, create react native app keeps it simple for beginners and to get started. As you set up more complex views you will find you need to have a separate view for ios and Android.
If you structure your app well, you can split the logic into one file and then have a separate view for ios, Android and even web. Essentially writing 1 app for 3 platforms.
index.js will run on both platforms. index.ios.js will only run on iOS devices while index.android.js only runs on Android devices.
If you have a view that is going to look the same on both devices and any dependencies you have run on both platforms in the same way skip the platform specifier.
If, however, the view needs to look a bit different on the two platforms(to follow differing design standards on the two platforms perhaps) or you need to use different dependencies on the two platforms then you need to use the specifiers.
By having some components be simply .js and others be .io.js or .android.js it allows you to consolidate code where possible while still being able to make platform specific choices when needed.
It should be noted that the platform specifiers can be used on any component, not just index files. (i.e. You can have MyCoolButton.js that will be used on both platforms and MyRegularButton.ios.js and MyRegularButton.android.js` that will each get used on the appropriate platform automatically.)
if you will see this repo https://github.com/react-community/create-react-native-app you'll know that create-react-native-app is Expo product. All your app compiling on Expo servers and index.android.js and index.ios.js located there.
If you want to modify platform files, you need to run
npm run eject
After that, you'll get a raw react-native project with all dependencies (npm, cocoapods, react-native modules) and of course index.android.js and index.ios.js
React Native components will port to their platforms so yes, you can build everything in index.js and be fine for most cases.
If you have certain styles or using some components that only have platform specific features, you can either use the .ios or .android tags to help that so it puts that scaffolding out there.
There is also the Platform module that you can use for simple stuff but the React Native guide, it mentions the use of ios and android tags on files if your code gets too complex.
https://facebook.github.io/react-native/docs/platform-specific-code.html