I recently worked on a legacy React Native app that had issues running on Android. Like many software projects there is never enough time nor enough engineers so the project was not tested for Android. When they finally got around to running the app on Android it was too painful. I was asked to fix it.
Before going over the lessons learned lets explain what AndroidX is and why it has caused the react native community so much pain? Google essentially fixed the naming conventions of many of its core libraries. That’s all AndroidX is. Within normal Android projects developed in Android Studio the upgrade path was easy. But not for RN.
In RN we do not typically compile the native dependencies. We instead rely on the dependencies to deliver a compiled file that can be linked by RN. So we have a hard division, RN apps 0.59 and below or RN apps 0.60 and above.
Do you have a situation where you are on RN 0.60 or above, but one of your dependencies has not upgraded to AndroidX yet? Jetifier will search through your npm dependencies, detect old android imports and modernize them. If you are on RN 0.59 or below you do not need to run jetifier. If you are on RN 0.60 and above jetifier is run for you automatically.
One of the first things I addressed was getting the project to build properly
version that is known to work. In
package.json there is an engines
field. You should review and pick an LTS version of nodejs
you are committed to making the project run on. You may end up with something
While you are at it you can use asdf and specify the
language runtimes required for your project. You can add a
that reads like
Once you have
npm install running correctly be sure to add
in version control. Yes it should be tracked as that is a set of dependencies
that is known to work for the project.
Now you try to build your app
$ react-native run-android but you see errors
These types of errors seem to map one to one to entries in
android/app/build.gradle in the
dependencies group. You should specify the
exact version of the dependency to make the build complete.
If your project is heavily customized it may be hard to even know what a correct
RN app looks like. For extreme cases you can compute a diff on the config files
against the example app for your RN version.
Luckily the RN team has provided example builds for every
version of RN. E.g. RN 0.57 build.gradle file.
These examples are accessible by picking the correct branch and opening
local-cli/templates folder. Note, these are the example apps that are
generated by the cli when you initialize a new project.
To get the app building I specified the android sdk version. This in turn required using a version of gradle around 5.x (5.6.2 for us). Something that confused me a lot was the mismatching numbers between the gradle version and the android plugin for the very same gradle version. You want to set the plugin to version 3.5.0. The gradle syntax for the wrapper task also changed between these gradle versions. You end up with
You also need to upgrade the gradle version in
If your app is RN 0.59 and below be sure to use dependencies that do not use
AndroidX. This means reading through the dependencies releases on github, e.g.
https://github.com/react-native-community/async-storage/releases and looking
for the last release that was published before June 2019 (or thereabouts,
read the release notes for the first mention of AndroidX). You can quickly list
the possible versions by running
$ npm view <package name> versions.
You can also review dependencies generated by gradle. You will be shown output like
This region of gradle output lists some AndroidX dependencies being brought into
the project. Following Top-Master’s stackoverflow answer, we see that
is pulling in some AndroidX dependencies. In this particular case we can search the
firebase release notes for the string
and see an annoucement on June 17th that the library was migrated over to AndroidX.
android/app/build.gradle file listed
which we can see from the notes was released after June 17th. The fix was to downgrade this to 16.0.8.
You will have to repeat a similar process for every dependency that is not building correctly for you.
This project was using react-native-firebase. For these projects be sure to consult the compatibility table. Mainly you’ll want the correct version of play services listed in your build.gradle file
This project was complaining about realm building. For this I ended up upgrading the dependency so it could build correctly with gradle 5.x. Similar process, I read through the releases and found the smallest version that would work with a modern gradle version.
If you need help solving your business problems with software read how to hire me.