react-native-netinfo: getConnectionInfo returns wrong info if network state changes while app is "sleeping" in background
Environment
React Native Environment Info: System: OS: Windows 10 CPU: (4) x64 Intel® Core™ i5-3230M CPU @ 2.60GHz Memory: 6.47 GB / 15.95 GB Binaries: Yarn: 1.13.0 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 6.4.1 - C:\Program Files\nodejs\npm.CMD IDEs: Android Studio: Version 3.3.0.0 AI-182.5107.16.33.5314842
Platforms
I’m experiencing the issue on both iOS and Android.
Versions
- Android: 7.1.2
- iOS: 12.1.4
- react-native-netinfo: 1.3.0
- react-native: 0.59.1
- react: 16.8.3
Description
If the network state changes while the app is in background, NetInfo.getConnectionInfo() returns the older state until the state changes again with the app in foreground. A similar issue was opened on 4 Oct 2018 on the react-native repo: https://github.com/facebook/react-native/issues/21476. I don’t know if it’s a regression or not.
Reproducible Demo
I call the function when the instrested component mounts:
static getDeviceConnectionInfo = async () => {
const info = await NetInfo.getConnectionInfo();
Reactotron.log('G O T N E T I N F O', info);
return info;
}
It returns the correct state. If I disable the WiFi (for example) and re-mount my component (it’s a modal that I mount/unmount) the state I get is correct and updated (type === unknown).
Now i put the app in background and I re-enable the WiFi. Then I resume the app and open the modal again. The state returned is still type === unknown.
The state I get doesn’t update until I make another network change with the app in foreground.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 1
- Comments: 16
Ok, that makes sense. I hadn’t come across that library before.
In that case, option 2 might affect that, so I will try option 1 as a solution instead 👍
Thanks again for the excellent reproduction repo. That made it very easy to debug this 👍
The network information callback is not called on Android when the app is in the background and is not called when the app comes back into the foreground. This is because we are explicitly unregistering on “pause” and re-registering on “resume”. As
getConnectionInfouses a “cached” value it returns an outdated value.Possible fixes:
Overall, I think I favour the 2nd approach as we should be aiming to minimise battery use as much as possible and it’s unlikely that most apps care about the network state when they are in the background.
I will experiment and look for a fix to this.
The difference between Android versions with the
unknownandnonestates is due to some differences in the way the two providers are implemented. Broadcast receivers for older Android versions correctly reportsnonewhereas the newer API incorrectly reportsunknown(it basically doesn’t handle thenonecase). I have opened a new issue #44 to track this.I’ve created a minimal rn project that reproduce the issue on Android (and prove that on iOS everything works fine). https://github.com/filippoitaliano/net-info-test.
I have some additional information:
unknown. I’ve seen the stringnoneonly with other Android versions (or on iOS);unknownuntil the first change with the app in foreground.P.S. I can reproduce the issue also with the latest version of react-native-info.
Thanks so much for the extra information. To make this as easy as possible to debug and fix, can you provide a link to a Github repo with the simplest app which shows the bug. Just a single screen with a button will do. That will really help me to look into this properly!