
A while ago, I was working and was faced with the task of developing a react-native application to track vehicles. After spending about a month researching and trying out different ways of doing background geolocation in react-native applications, I found out that: it was very hard; there were no posts that compiled all the information on the topic. So I decided to write this post for anyone who faces the same problem.
The problem was fairly simple: when a user pressed Start, start tracking his location and notify the server. Keep doing that until the user hits Stop. While this sounds trivial, I can assure you the solution is not.
1st approach – expo sdk
I love using Expo SDK. It is very simple, no more dealing with Android Studio and Xcode, you do not even need a Mac computer anymore. But it has a major drawback: you cannot use native modules. That includes not only the modules you could write yourself but also all kinds of libraries for react-native that require linking (e.g. https://github.com/azlyth/react-native-ssh).
Until recently, Expo SDK was out of the question for background geolocation for this very reason. But, after countless asks from the community, Expo now has the ability to do background-geolocation (!) from the box (!). That sounded too good to be true, so I decided to give it a go.
is it to good to be true?
Yes. You can read up the documentation here (https://docs.expo.io/versions/latest/sdk/location/#locationstartlocationupdatesasync) and it is in the changelog (https://github.com/expo/expo/blob/master/CHANGELOG.md) for version 32.0.0. Basically, they did it in the style of Expo, requiring minimal setup for getting started with background geolocation (it requires calling 2(!) functions). However, it is at a very early stage. Implementation is inconsistent between IOS&Android, background service gets killed randomly, accuracy is basically nonexistent regardless of parameters that get passed to the initializer, callback function does not get called. In short, I found it unusable for my purposes and cannot think of any use case where this would be useful. Let me know in the comments about your experiences with Expo SDK and their background geolocation service, I would love to be wrong about it.
2nd approach – native code
As soon as Expo SDK was off the table, I thought about writing the code natively. The problem was obvious: while I had some experience in Java, I never ever used Swift/Obj-C and had no idea where to begin.
Firstly, I decided to write a module for android only as a proof-of-concept and think about IOS module later (spoiler: I never got to the IOS module). It was fairly easy: I followed this(https://facebook.github.io/react-native/docs/native-modules-android) to make a native module and just followed Android docs on background services and location to finish it off.
The experience was way better than with Expo SDK from the beginning. Locations were accurate, arrived to the server on time, I had full control over implementation, the background service was unkillable. I was happy for a while until I realized I still have to somehow make this work on the iPhone.
I tried some workarounds like using a native module when on Android and a third-party library when on IOS, but that did not work out. I wanted consistency, shared codebase, and minimal native code, so I moved on to using third-party libraries.
3rd approach – libraries
There are two libraries related to background geolocation right now on github:
- https://github.com/mauron85/react-native-background-geolocation
- https://github.com/transistorsoft/react-native-background-geolocation
Both of them are open source (Apache 2 & MIT) and both of them do roughly the same thing. Both of them require native module linking so they will not work with the Expo SDK. But what is the difference?
While the one by transistorsoft is open source, it is not exactly free. If you want to build the app in production mode, you will have to purchase a license key for it. It comes with support, closed wiki and private github repo. I cannot say I agree with this approach, but it is perfect for conservative companies who do not really believe in free software and want a support line.
so which one?
Apart from paid perks, both libraries are more or less the same and I had great success with both of them. I am not going to tell which one made it in production for my project, but I can tell that it was a close call and any of these two would do the job with success. The development on the mauron85 github repo looks active, with issues issued, pull requests pulled and commits being committed. Check it out, or even contribute, if you feel like it.
Conclusion
While react-native is still not the best way to go for background geolocation, the progress is clearly noticeable and the ecosystem becomes better and better with every commit. At this point, I would still advise going with Java/Swift for location purposes if you know them. Otherwise, javascript, react-native and its library ecosystem will do the job.