React Native HMS Core with Expo

Expo

Expo can be a fantastic tool to speed up the development process, manage different platforms as well as credentials.

Unfortunately, there are still a lot of things missing to make this tool truly complete, and developers are reluctant to integrate certain technologies, due to the deep nature of Expo and its philosophy.

That’s why they launched the new eas-cli build system, which should finally replace the classic expo-cli service.

Huawei

Huawei having separated from Google, and the HMS (Huawei Mobile Services) is not yet integrated into the Expo environment. So some services like Map, push notifications, etc. cannot be used on the latest Huawei.
However, that represent a significant market share when you want to distribute an app to the general public.

That’s why I absolutely had to find a solution.

Expo plugins

It’s now possible to create Expo plugins to modify certain resources before the Expo prebuild phase, i.e. the creation of config files relating to Android and iOS.
So I started from this principle to add everything the HMS Core needed to work.

Steps

  1. Huawei developer account
    Start by creating your account on AppGallery
    If you represent a company, you will need to fill out a form so that Huawei can verify your informations and grant or deny you access to its platform. The verification process can take 1–2 days.
  2. Plugins
    I created 3 plugins which use hooks from @expo/config-plugins and which allow to add the different dependencies and permissions in the project.gradle, app.gradle, and AndroidManifest files.
  • Project Gradle
    Huawei native dependency
  • App Gradle
    Importing the Huawei config plugin
  • Manifest
    Add AppGallery permission

3. List your plugins

Don’t forget to reference your plugins in app.config.js or app.json for them to be applied

"plugins": [
"./android-custom-permissions-plugin",
"./custom-project-gradle-plugin",
"./custom-app-gradle-plugin",
...

4. Add Huawei Services File

Like Google, setting up your app on the AppGallery will generate a services file to put into your project.
With this difference that for Google, Expo manages the process and therefore you only have to reference it in your app.config.js or app.json and paste the file in the root of your project.

Here you will have to put it in /android/app which is only created after the prebuild phase.

So I decided to make a post-install script (after the prebuild phase of installing dependencies) in order to move the file to the correct folder.
If you have a better solution, feel free to reach me!

In my package.json:

"scripts":{"eas-build-post-install": "mv agconnect-services.json android/app/agconnect-services.json"

Note:
If you are using differents eas build profiles with differents package name, and so, differents config files, you can use env variables here,and check if this file exist, as well as android folder, who doesn’t exist on iOS:

[[ -f agconnect-services-${EAS_BUILD_PROFILE}.json ]] && [[ -d android ]] && mv agconnect-services-${EAS_BUILD_PROFILE}.json android/app/agconnect-services.json  || echo 'No huawei services files or no android folder'

5. HMS libraries

Finally, install the HMS libraries you need here
https://github.com/HMS-Core/hms-react-native-plugin

Please note that some libraries may require additional steps, for my tests I used MapKit

6. Build

Finally, create a new build with eas build, upload your apk to your Huawei device, and voila!

MapKit screenshot

Notes

Manage your Keystore file
As with Google services, you need a Keystore file generated with keytool.
Either create one manually or let Expo handle that process, but you’ll need to upload it to the AppGallery.

Obfuscation
Be careful, if you obfuscate your code via proguard, you will have to add an exception in the proguard-rules.pro file or use Expo BuildProperties

https://docs.expo.dev/versions/v45.0.0/sdk/build-properties/
https://developer.huawei.com/consumer/en/doc/HMS-Plugin-Guides/config-obfuscation-0000001061770075-V1

Conclusion

Expo remains a powerful and practical framework, but this kind of problem can discourage more than one, and I really hope that in the future it will be easier to integrate native libraries and that the documentation will be clearer.

I had never written an article but I found the documentation’s so poor and no one seemed to be interested in this problem (or not sharing their solutions), that I wanted to share this with everyone.
I hope I was able to help some people because I really had a hard time finding informations about expo plugins, and I had to do a lot of tries before I got there.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store