This article examines common issues encountered when building apps for Android using React Native. It shows errors you're likely to see, and how to resolve them. It also offers tips on troubleshooting.
In this tutorial, we’ll take a look at how to debug some of the most common issues you will encounter while developing Android apps with React Native. Specifically, we’ll be looking at the following issues:
This article assumes you know how to develop apps with React Native. It also assumes that you have set up your computer for React Native development.
This article assumes you know your way around the operating system you’re using, especially when executing commands in the terminal or installing software.
In this section, we’ll take a look at a general debugging checklist that can help you identify the actual issue that you’re having.
node_modules
and re-install all the packages:1rm -r node_modules 2 npm install
After that, execute the following:
1cd android 2 ./gradlew clean
This will delete the build
directory and make sure that no previous code or resources are still being cached.
You may even go one step further by clearing out the Gradle’s dependency cache:
1./gradlew build --refresh-dependencies
Once that’s done, go back to your project’s root directory and execute react-native run-android
like usual.
In this section, we’ll be looking at problems you might encounter if you haven’t installed all the software dependencies for React Native for your operating system. Or if there are problems with the tools used for building the app.
The first time you build your Android app after setting up your computer for React Native development, you might encounter an issue similar to the following:
The terminal says the problem is:
1FAILURE: Build failed with an exception. 2 3 * What went wrong: 4 A problem occurred configuring project ':app'. 5 > SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.
This happens when you haven’t properly configured your environment variables to use the path where Android is installed. React Native requires this if you’re running the app on Android.
To solve the issue, you need to add the Android path to your environment variables.
In Ubuntu, this can be done by editing the .bash_profile
file located in your home directory:
1nano ~/.bash_profile
Add the following to the file then save it:
1export ANDROID_HOME=$HOME/Android/Sdk 2 export PATH=$PATH:$ANDROID_HOME/tools 3 export PATH=$PATH:$ANDROID_HOME/tools/bin 4 export PATH=$PATH:$ANDROID_HOME/platform-tools
Then you can execute the following command to propagate the change to your system:
1source ~/.bash_profile
For Mac OS, you can also make use of the ~/.bash_profile
file. Here’s the equivalent:
1export ANDROID_HOME=/Users/$USER/Library/Android/sdk 2 export PATH=${PATH}:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools
Another issue which you might encounter when first starting out is that the Android packages required by React Native are not installed.
You can solve this by opening Android studio, then click on the configure button and select SDK Manager. That should open the following window:
Check the same packages I’ve checked above. Here’s the text version:
Next, under the SDK Tools tab, the requirement is Android SDK Build-Tools version 23.0.1
.
Go through the installation process and that should solve the issue. Note that the items I’ve checked are the ones that are required by React Native.
If you’re using Google Play services in your project, you should install the following packages from the SDK Tools as well:
Emulators are an indispensable part of the app development process. They allow us to test the app on different devices from our development machines. But along with the convenience they afford, are problems which only occur when using them.
For Android, the most common problem is the lack of the Google Play service within the emulator. If you’re using a native module which uses the service or if you’re using it directly from your app, then you may get the following error when using emulators. This is especially true if you’re using Genymotion or the Android emulator in Android Studio:
In the screenshot above, the app is complaining that it won’t run without the Google Play services.
If you’re using Genymotion, you’re in luck because they’ve added a really easy way to install Google Play services. Simply click on the Open GAPPS button located at the upper right side of the window and just go through the installation wizard.
Once it’s installed, restart the virtual device and you should be good to go.
Sometimes, you’ll also encounter problems with the build tools that React Native uses for building the app or running the development server.
React Native uses Watchman to watch the project files for changes. This allows you to automatically rebuild the app so the changes will be reflected on the emulator or device as you’re developing.
Here’s the error that you’ll usually get if there is a problem with Watchman. This problem usually occurs in Ubuntu, but it can occur in other operating systems as well:
The build log says the error is:
1Could not run adb reverse: Command failed: /home/wern/Android/Sdk/platform-tools/adb -s 192.168.56.101:5555 reverse tcp:8081 tcp:8081
Unfortunately, Googling the error “could not run adb reverse react native” doesn’t really return results which point out to the actual cause of the problem. It only gives us the idea that something is wrong with the development server.
To solve this issue, you need to run the development server separately. You can do that by executing react-native start
.
This returns the actual error which prevents the development server from running automatically:
If you are to take anything out of the screenshot above, it’s this:
1inotify-add-watch(/home/wern/dev/mobile/TestProject/android/app/build/intermediates/incremental/mergeDebugResources/merged.dir) -> The user limit on the total number of inotify watches was reached; increase the fs.inotify.max_user_watches sysctl 2 3 All requests will continue to fail with this message until you resolve 4 the underlying problem. You will find more information on fixing this at 5 https://facebook.github.io/watchman/docs/troubleshooting.html#poison-inotify-add-watch
Unfortunately, the solution presented isn’t really very helpful. Especially if you don’t have much experience with Linux commands.
Here’s are the commands which you need to execute:
1sudo sysctl fs.inotify.max_user_instances=99999 2 sudo sysctl fs.inotify.max_user_watches=99999 3 sudo sysctl fs.inotify.max_queued_events=9999
This raises the limits of the inotify-watches
to a really high value. Setting it to a value of 99999
is like saying to Watchman to use however much resource it needs to watch the directories. Because the underlying issue here is that Watchman wasn’t able to allocate the resources it needs because the default values were too low.
After that, shut down the Watchman server so the changes will be reflected in the system:
1watchman shutdown-server
Once that’s done, executing react-native start
should work smoothly. You can even skip it and just run react-native run-android
because that will also run the development server in the background. Be sure to terminate the currently running process before you proceed (press Ctrl + C
or Cmd + C
on your keyboard).
Gradle is the build tool used for Android app development. React Native also taps into it in order to build and compile the app to an executable .apk
file.
The most common problem that you might encounter, especially when your project is using a lot of third-party native modules, is the collision of Gradle dependencies. Collisions occur when two or more native modules are using different versions of native dependencies.
The most common among the native dependencies which cause a collision is the Google Play service. Any native module which uses Google’s services (for example, Firebase, Google Maps, AdMob) imports Google Play services as one of its native dependency.
The good news is someone has already written about this subject in really nice detail, so I’ll just point you out to the article: How to solve Google Play Services version collision in Gradle dependencies.
In the future, it’s always a good idea to check whether you’ll have a potential collision before installing a specific module. You can do that by opening the android/app/build.gradle
file on the modules Github repo.
For example, here’s the build.gradle
file of the React Native AdMob module. Check the packages under the dependencies
to find out whether you will have a collision. And then use the article I’ve pointed out above as a guide for dealing with the collision:
1dependencies { 2 compile 'com.facebook.react:react-native:+' 3 compile 'com.google.android.gms:play-services-ads:+' 4 }
In this section, we’ll be looking at issues commonly encountered when using third-party packages (For example, the ones you install via npm or Yarn).
As a case study, we’ll be looking at React Native Maps. In my opinion, it’s the most notorious React Native package for breaking builds. Especially if you’re using it with other packages that depend on different versions of libraries that React Native Maps relies on.
I’ll walk you through an empty project which will use React Native Maps. At the time of writing this article, you’ll most likely have problems with getting React Native Maps to work. So we’ll try to install the package and solve any issue that we encounter.
If you haven’t generated a new React Native project yet, go ahead and create one:
1react-native init TestProject 2 cd TestProject
Once that’s done, install React Native Maps:
1npm install --save react-native-maps
If you read the installation instructions for Android, it says that you should add the following to the android/app/build.gradle
file:
1... 2 dependencies { 3 ... 4 implementation project(':react-native-maps') 5 }
But checking the current contents of the dependencies
, you’ll see the following:
1dependencies { 2 compile fileTree(dir: "libs", include: ["*.jar"]) 3 compile "com.android.support:appcompat-v7:23.0.1" 4 compile "com.facebook.react:react-native:+" // From node_modules 5 }
Right off the bat, you’ll notice that implementation project(':react-native-maps')
doesn’t seem to fit in. And fair enough, you’ll see someone having an issue with this bit of code.
Someone replied to that thread and they said that the project should use Gradle 3 in order for the code to work.
But if you’re like me and you’re using a bunch of other native modules on your project, then this advice isn’t really going to work. Gradle is the build tool which compiles the project into an app. So using a different version for different packages isn’t going to work. All the native modules that you’re using for your project should use Gradle 3.
If you check the projects with the most number of stars on Awesome React Native and go to their android/build.gradle
file. You’ll notice that most (if not all) of them are still using a lower version of Gradle (ranging from Gradle version 1 to 2):
As a web developer with limited knowledge on native Android app development, converting the existing code of each of the modules that I’m using to Gradle 3 syntax isn’t really the best use of my time. Especially if there is a deadline to meet.
So what’s the solution?
Unfortunately, the only solution is to downgrade to a lower React Native Maps version. One that still uses the same Gradle version as most of your native modules. Note that downgrading to a lower version means you won’t get the latest improvements for the library.
Start by uninstalling React Native Maps:
1npm uninstall --save react-native-maps
If you have already gone through the installation steps, undo them by undoing the installation instructions.
Next, go to React Native Maps’ releases page and install the latest version which doesn’t use Gradle 3. In this case, it’s version 0.20.1
. Because if you check the release notes of the version that came after it, it said “Updated gradle configuration for gradle 3.0.0+”.
Go ahead and install it:
1npm install --save react-native-maps@0.20.1
After that, follow the installation instructions for that version.
After making all the changes, try running react-native run-android
again.
If you’re like me and you haven’t installed the Android packages required by React Native Maps, you should get an error similar to the following:
The error is:
1[Android SDK Build-Tools 25.0.3, Android SDK Platform 25]. 2 Before building your project, you need to accept the license agreements and complete the installation of the missing components using the Android Studio SDK Manager.
You can solve the issue by opening the SDK Manager from Android Studio. And under the SDK Tools, check version 25.0.3
under Android SDK Build-Tools:
After that, and it still doesn’t work, be sure to check out the Troubleshooting section on the React Native Maps’ repo for the specific version that you’re using.
That’s it! In this tutorial, we’ve taken a look at some of the techniques you can use to debug issues you’ll commonly encounter when developing apps with React Native. Hopefully, this article has given you a better idea of how to go about debugging these kinds of issues in the future.