How I solved Google Play's Android asset verification for Expo apps
Google Play Console needs adi-registration.properties in native Android assets. Expo's JS bundler won't put it there. So I wrote a config plugin that does.
If you've ever tried to verify package ownership on Google Play Console for an Expo-managed app, you've probably hit this wall: Google gives you a adi-registration.properties file and tells you to place it in your app's native Android assets directory. Simple enough — except Expo's JavaScript asset bundling doesn't put files there. Files go into the JS bundle, not into android/app/src/main/assets/.
Without a custom build step, your verification fails. I spent a few hours on this before deciding to fix it properly.
What Google Play actually needs
Google Play Console's package ownership verification checks for this file at a specific native path:
android/app/src/main/assets/adi-registration.properties
It must be present in a signed APK you upload through the console. If it's not at that exact path, verification won't pass.
Why Expo makes this tricky
In a bare React Native workflow you'd just drop the file in the right folder and commit it. But in an Expo managed workflow, the android/ directory isn't committed — it's generated during eas build. So you can't manually place files there because there's no "there" until the build runs.
The right solution is an Expo config plugin: a function that runs during the native code generation phase and places your file exactly where it needs to go.
The plugin: expo-adi-registration
npm install expo-adi-registration
You get two ways to use it depending on how you prefer to handle the token.
Option A — Pass the token directly in config (recommended)
If you don't want to commit the properties file at all, pass the token string straight from app.config.js. The plugin writes the file during build:
// app.config.js
export default {
expo: {
plugins: [
["expo-adi-registration", { "token": "YOUR_TOKEN_FROM_GOOGLE_PLAY_CONSOLE" }]
]
}
}
Pair this with EAS Secrets so the token never lands in your repo:
eas secret:create --scope project --name ADI_TOKEN --value "your-token-here"
Then reference it in your config:
["expo-adi-registration", { "token": process.env.ADI_TOKEN }]
Option B — Place the file in your assets folder
If you'd rather keep the properties file on disk:
- Create
assets/adi-registration.propertiesin your project root - Paste your token snippet from Google Play Console inside it
- Add the plugin without options:
// app.config.js
export default {
expo: {
plugins: ["expo-adi-registration"]
}
}
The plugin finds the file in assets/ and copies it to the right native path during the build.
Build and verify
Once the plugin is configured, trigger a release build through EAS:
eas build -p android --profile preview
Upload the generated .apk to Google Play Console. Verification should pass because adi-registration.properties is now in android/app/src/main/assets/ inside the APK — exactly where Google looks for it.
What the plugin actually does internally
During eas build, Expo's prebuild phase runs all config plugins before the native Android project is compiled. The plugin hooks into that phase, resolves the source of the properties file (either the inline token or the file from assets/), and copies it to the native assets path.
No changes to your JS bundle. No changes to your Expo SDK setup. It runs once at build time and gets out of the way.
Requirements
- Expo SDK 49 or higher
- EAS Build (not
expo build— that's deprecated)
If you're hitting this problem, the package is on npm: expo-adi-registration. Issues and PRs welcome on GitHub. If something doesn't work for your setup, open an issue with your SDK version and I'll take a look.