add EMM / MDM support to react native expo application

How to add EMM support for an expo managed react native application?
I see GitHub - robinpowered/react-native-mdm: Mobile Device Management tools for React Native and GitHub - mattermost/react-native-emm: React Native package for EMM managed configurations
Both are not compatible with expo.
Has anyone integrated with EMM, specifically to get the app config for the mobile app?
Appreciate any pointers

Hi @sonuchandra

From a quick look at those two projects, react-native-emm looks like it should work out of the box with Expo as long as you build with EAS Build. It will not work with Expo Go, but you can create a development build to use instead of Expo Go.

react-native-mdm will need a pretty simple config plugin in order to make the necessary changes to AndroidManifest.xml.

For how to write a config plugin to make the necessary changes to AndroidManifest.xml, see the following:

Thanks @wodin
(I am new to react native, expo)
How do you determine that a config plugin will be needed, is it because AndroidManifest.xml needs to be updated?
Android needs the app_restrictions.xml as well. That is stored in the res/xml folder and declared in the AndroidManifest.
How can I achieve that?

Yes, basically if the installation instructions tell you to modify anything under ios or android then a config plugin will be needed. Except for pod install which is run automatically by Expo’s build servers.

The react-native-emm installation instructions for iOS just say you must run pod install. Since that is handled for you by the build server, you don’t need to do anything other than installing the dependency with npm or yarn. You can ignore the stuff about older React Native versions, because that’s not relevant to current versions of Expo.

They do say something about “Using CocoaPods (required to enable caching)”. I’m not quite sure what they mean by that. The “pod” in “pod install” refers to CocoaPods. So maybe that section of the installation instructions is also about old versions of React Native. Anyway, I don’t think you need to worry about that.§§

The Android installation instructions mention a minimum Android SDK version. That’s fine, because Expo targets a higher Android SDK version by default anyway. If you ever need to tweak that you can use BuildProperties for that. There’s nothing you need to do for recent React Native versions and you can ignore the instructions for older React Native versions. The instructions about settings.gradle, app/build.gradle, and can be ignored. “Autolinking” should take care of those things automatically. As the instructions say, you would only need to worry about those “if you have trouble”. But actually, in a Managed Expo app you should never get into the situation where you might need to do that stuff manually.

I see that I missed the part about AndroidManifest.xml yesterday. My opinion is that the installation instructions of React Native libraries often make things more difficult to understand than they should.
AndroidManifest.xml is one of the easiest things to write a config plugin for.

Yes, but there’s no built-in mod plugin like “withAndroidManifest” for updating xml/app_restriction.xml. Maybe look in the expo/expo repository to see how things like withAndroidManifest and are implemented. Or and withStringsXml. Or and withAndroidColors.

@wodin Thanks so much for your response.
Looks like for both the libraries I will need

  • a development build to get Expo Go working.
  • config plugin for modifying AndroidManifest
  • config plugin for creating and writing res/app_restrictions.xml

Am I correct?

For react-native-emm, how would the step ‘npx pod-install’ be run for Expo go?

I would be curious why ‘npx pod-install’ is not needed for the react-native-mdm library?

Yes, that’s correct.

I assume you mean for the development/production build? Because as you said above, these libraries won’t work with Expo Go.

Have a look at the EAS Build iOS build process. When you run eas build there are some steps that run on your local machine (the “local steps”). Then the project is uploaded to the build server and the rest of the process runs there (the “remote steps”).

Step 10 of the remote steps is: “Run pod install in the ios directory inside your project.”

i.e. you don’t need to worry about that step. It’s run automatically on the build server.

Thanks @wodin

I wrote a config plugin to modify the AndroidManifest.xml
Whats the best way to test it locally?

Currently, Im testing by creating an eas build, but thats too time consuming

Can you please point me to an example to create app_restrictions.xml in xml folder for Android
The restrictions file needs to look like below:

<?xml version="1.0" encoding="utf-8"?>

From : Set up managed configurations  |  Android Developers

What I have done in the past is this:

  • Make sure everything is checked into Git
  • Run npx expo prebuild -p android --no-install to generate the native Android project and apply the config plugins
  • Verify that the config plugin did what you expected or see what went wrong.

Depending on how comfortable you are with Git, you might want to delete the android directory and revert all of the other local changes (e.g. to package.json and package-lock.json or yarn.lock) before continuing. Otherwise, if you’re comfortable with committing only the relevant changes you can tweak the plugin, commit just the fix (without committing the android directory and other changes made by prebuild), and run npx expo prebuild -p android --no-install --clean to check the results.

After you’ve finished debugging, delete/revert all of the changes that npx expo prebuild made.

$ git status
$ git checkout -- package.json .gitignore
$ rm -r android index.js metro.config.js

or if you’re sure you had everything checked in at the start and all of the fixes checked in along the way, you could do this to clean up:

$ git clean --force && git reset --hard

You could also try using npx expo config, but I prefer running prebuild and checking the files directly.

% npx expo config --help

    Show the project config

    $ npx expo config <dir>

    <dir>                                    Directory of the Expo project. Default: Current working directory
    --full                                   Include all project config data
    --json                                   Output in JSON format
    -t, --type <public|prebuild|introspect>  Type of config to show
    -h, --help                               Usage info

There’s also a VS Code extension that might work for you. I haven’t tried it, since I don’t use VS Code:

I wrote something like that in October 2021 (with later tweaks):

It should probably be marked as “Dangerous”, since it doesn’t try to play nicely with any other potential config plugin that might want to manipulate the same file. Also, I wrote it without looking at the implementation of things like withAndroidManifest. I am sure it could be improved.

I was able to integrate with the react-native-mdm (react-native-mdm - npm) library via a development build
I wanted to confirm that including it in the package.json would be sufficient to include the libraries when we do release builds for Android and iOS?
we use eas build to create the apk and ipa for Android and iOS respectively

Yes, as long as you install react-native-mdm with yarn or npm (so it’s in your dependencies in package.json and also in yarn.lock or package-lock.json, depending on what you use to manage your dependencies), the build server will install it and include it in the app.

The above plus the config plugin should be sufficient.

Thank you @wodin