Exploring the compatibility of Facebook’s React with Google’s IoT Platform
With the explosion of the Internet of Things in recent years, it is no surprise that Google would want to get developers involved using the Android OS. The resulting product is Android Things (first released in May 2018), a version of the Android OS specifically designed for IoT devices. Based on the same operating system as Android phones, Android Things simplifies the development process and makes creating IoT programs the same procedure as a phone or watch app, but the available libraries are different depending on the IoT hardware.
While React-Native supports iOS and Android phones out of the box, the project creation tool does not support Android Things by default. With this in mind, we aimed to test the compatibility of React Native with Android Things, and if possible, port our Metro Tracker web app written in React to the Android Things platform.
What We Did
Our original Metro Tracker web app was written using React, and takes advantage of the API provided by Washington Metropolitan Area Transit Authority (WMATA). Upon selecting a station from the dropdown menu of all stations, the app displays a formatted table of train information, resembling the billboard present in all of DC’s metro stations. This table can display the incoming train colors, destinations, and times until their next arrival. Additionally, a map is drawn using SVG to provide a graphical representation of the train locations between stations.
The first step to running our Metro Tracker on Android Things was to prove that it was possible to run React-Native at all, as at the time of writing there is a lack of documentation about running React on Android Things, due to its novelty. After creating a skeleton Android Things app, we followed the React-Native documentation for adding React to existing apps, as the React-Native project generator can only target the Android phone platform. We kept our fingers crossed that the Android Things code would be compatible, and upon hitting “build” in Android Studio, we were greeted with the friendly “Hello, World!” of the React-Native demo code, meaning that we had React successfully compiling to Android Things.
Now that we had a template to run React-Native code on Android Things, the fun part was porting the Metro Tracker app to React-Native. As it turns out, React-Native is incapable of rendering HTML out of the box, meaning that our entire interface had to be rewritten. Fortunately, the back-end code did not really have to change, so we only had to create or find components to replace the HTML elements that we had used in the original web app. The React community has published a large number of generic components to the Node repositories, making it easy to add pre-written interface components to a project. As a result, a bulk of the UI porting was just a matter of finding React-Native components to replace our HTML.
Once we had all of our replacement components, all we had to do was ensure that our back-end was feeding data correctly to the new pieces, and we had our Metro Tracker successfully running on Android Things, with only minimal Android coding required.
The main challenge with this project was the general lack of documentation, as we were unable to find any information regarding Android Things specifically working with React-Native, and the hardware constraints of the Android Things device meant that a lot of the normal Android documentation from React did not apply. One example of this was the React assets bundle, which normally would be transferred to the Android app when the phone scanned the QR code to install the app. Because the Android Things device has no support for QR codes, however, the app has to be manually installed every time, but the documentation we found to do that caused an error about a “missing assets bundle.” Some Stack Overflow articles revealed that we had to manually create the bundle ourselves, then install the app. To alleviate some of the headache, we made a bash script to automatically make a new bundle and then install the app to the device. Nonetheless, there was no single source of information to resolve this issue, and we had to research a variety of different problems to get a working solution.
A second issue related to documentation was getting the React-Native console logs from running the Android Things app. For the first half of the porting process, it was not immediately obvious how to get those logs, meaning that debugging was happening by exclusively reading error messages on the tiny Android Things screen, as there was no way to print additional information. While this was not impossible, discovering the “react-native android-logs” command meant we could now send debugging messages to the console, which made the entire process much easier.
Now that we have our Metro Tracker successfully working on Android Things, there are a number of different directions we can follow. First and foremost, we can improve the Metro Tracker UI to be better optimized for the small Android Things screen, as we simply copied the original UI design. While it works well on a laptop or phone screen because a browser can resize automatically to fit everything, React-Native does not have that feature, so we currently have too much information being displayed on the small screen, making it impractical to use in real life.
A more general direction we can explore, however, is using other IoT hardware with Android Things and React-Native. While this particular project only uses the the screen attached to the Android Things device, future projects could explore how to integrate various IoT sensors into a React-Native app.