What happened?
I try to use the Expo-Plugin as described in the documentation. But it's getting underlined in the app.json with following message:
_Package "react-native-google-mobile-ads" does not contain a valid config plugin.
Learn more: https://docs.expo.dev/guides/config-plugins/#creating-a-plugin
Unexpected token 'typeof'(INVALID_PLUGIN_IMPORT)_
What to do to fix it?
Platforms
Android and iOS
React Native Info
Are your using Typescript?
package.json
"dependencies": {
"@expo/metro-runtime": "~6.1.2",
"@expo/vector-icons": "^15.0.2",
"@gorhom/bottom-sheet": "^5.2.6",
"@noble/hashes": "^2.0.1",
"@react-native-async-storage/async-storage": "2.2.0",
"@react-native-community/datetimepicker": "8.4.4",
"@react-navigation/native": "^7.1.6",
"axios": "^1.10.0",
"deepl-node": "^1.20.0",
"drizzle-orm": "^0.44.5",
"expo": "54.0.22",
"expo-background-task": "~1.0.8",
"expo-battery": "~10.0.1",
"expo-build-properties": "~1.0.9",
"expo-constants": "~18.0.9",
"expo-crypto": "~15.0.7",
"expo-dev-client": "~6.0.17",
"expo-drizzle-studio-plugin": "^0.2.1",
"expo-file-system": "~19.0.15",
"expo-font": "~14.0.8",
"expo-image-picker": "~17.0.8",
"expo-linear-gradient": "~15.0.7",
"expo-linking": "~8.0.8",
"expo-localization": "~17.0.7",
"expo-location": "~19.0.7",
"expo-network": "^8.0.7",
"expo-router": "~6.0.14",
"expo-secure-store": "~15.0.7",
"expo-sharing": "^14.0.7",
"expo-splash-screen": "~31.0.10",
"expo-sqlite": "~16.0.9",
"expo-status-bar": "~3.0.8",
"expo-system-ui": "~6.0.8",
"expo-task-manager": "~14.0.8",
"expo-web-browser": "~15.0.9",
"i18n-iso-countries": "^7.14.0",
"i18next": "^25.2.1",
"iso-639-1": "^3.1.5",
"lodash.debounce": "^4.0.8",
"react": "19.1.0",
"react-dom": "19.1.0",
"react-i18next": "^15.5.3",
"react-native": "0.81.5",
"react-native-aes-gcm-crypto": "^0.2.2",
"react-native-gesture-handler": "~2.28.0",
"react-native-google-mobile-ads": "^16.0.0",
"react-native-keyboard-controller": "1.18.5",
"react-native-localize": "^3.5.1",
"react-native-maps": "1.20.1",
"react-native-markdown-display": "^7.0.2",
"react-native-reanimated": "~4.1.1",
"react-native-safe-area-context": "~5.6.0",
"react-native-screens": "~4.16.0",
"react-native-svg": "15.12.1",
"react-native-view-shot": "^4.0.3",
"react-native-web": "^0.21.0",
"react-native-worklets": "0.5.1",
"react-native-zip-archive": "^7.0.2",
"ts-node": "^10.9.2",
"tsx": "^4.20.3",
"world-countries": "^5.1.0"
},
"devDependencies": {
"@babel/core": "^7.25.2",
"@eslint/eslintrc": "^3.3.1",
"@eslint/js": "^9.34.0",
"@testing-library/jest-dom": "^6.8.0",
"@testing-library/react": "^16.3.0",
"@types/better-sqlite3": "^7.6.13",
"@types/jest": "29.5.14",
"@types/lodash.debounce": "^4.0.9",
"@types/node-emoji": "^1.8.2",
"@types/react": "~19.1.10",
"babel-plugin-inline-import": "^3.0.0",
"better-sqlite3": "12.2.0",
"drizzle-kit": "^0.31.4",
"duckdb": "^1.3.2",
"expo-sqlite-mock": "^3.0.0",
"jest": "^29.2.1",
"jest-expo": "~54.0.13",
"react-test-renderer": "19.0.0",
"typescript": "~5.9.2"
},
app.json
{
"expo": {
"name": "xxx",
"slug": "xxx",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "xxx",
"userInterfaceStyle": "automatic",
"newArchEnabled": true,
"ios": {
"supportsTablet": true,
"bundleIdentifier": "xx.xxx.xxxx"
},
"android": {
"edgeToEdgeEnabled": true,
"permissions": [
"android.permission.ACCESS_COARSE_LOCATION",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.CAMERA",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.RECORD_AUDIO"
],
"package": "xx.xxx.xxxx"
},
"web": {
"bundler": "metro",
"output": "static",
"favicon": "./assets/images/favicon.png"
},
"plugins": [
"expo-router",
[
"react-native-google-mobile-ads",
{
"androidAppId": "ca-app-pub-....",
"iosAppId": "ca-app-pub-...."
}
],
"expo-localization",
[
"expo-location",
{
"locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location."
}
],
[
"expo-image-picker",
{
"photosPermission": "Allow $(PRODUCT_NAME) to access your photos.",
"cameraPermission": "Allow $(PRODUCT_NAME) to access your camera."
}
],
[
"expo-sqlite",
{
"enableFTS": true,
"useSQLCipher": true,
"ios": {
"customBuildFlags": ["-DSQLITE_ENABLE_DBSTAT_VTAB=1", "-DSQLITE_ENABLE_SNAPSHOT=1"]
}
}
],
[
"expo-splash-screen",
{
"image": "./assets/images/splash-icon.png",
"backgroundColor": "#0B4C6F",
"resizeMode": "contain",
"imageWidth": 200
}
],
"expo-secure-store",
"expo-background-task",
"expo-web-browser",
[
"expo-build-properties",
{
"ios": {
"useFrameworks": "static",
"deploymentTarget": "15.1"
},
"android": {
"minSdkVersion": 26
}
}
],
"./plugins/withAesGcmCrypto"
],
"assetBundlePatterns": ["assets/**/*", "db/*.db"],
"experiments": {
"typedRoutes": true
},
"extra": {
"router": {},
"eas": {
"projectId": "77c86bda-5768-4d5c-80a4-ff365269a374"
}
},
"owner": "mg83"
}
}
ios/Podfile
android/build.gradle
android/app/build.gradle
android/settings.gradle
AndroidManifest.xml
What happened?
I try to use the Expo-Plugin as described in the documentation. But it's getting underlined in the app.json with following message:
_Package "react-native-google-mobile-ads" does not contain a valid config plugin.
Learn more: https://docs.expo.dev/guides/config-plugins/#creating-a-plugin
Unexpected token 'typeof'(INVALID_PLUGIN_IMPORT)_
What to do to fix it?
Platforms
Android and iOS
React Native Info
Are your using Typescript?
package.json
app.json
{ "expo": { "name": "xxx", "slug": "xxx", "version": "1.0.0", "orientation": "portrait", "icon": "./assets/images/icon.png", "scheme": "xxx", "userInterfaceStyle": "automatic", "newArchEnabled": true, "ios": { "supportsTablet": true, "bundleIdentifier": "xx.xxx.xxxx" }, "android": { "edgeToEdgeEnabled": true, "permissions": [ "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION", "android.permission.CAMERA", "android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.RECORD_AUDIO" ], "package": "xx.xxx.xxxx" }, "web": { "bundler": "metro", "output": "static", "favicon": "./assets/images/favicon.png" }, "plugins": [ "expo-router", [ "react-native-google-mobile-ads", { "androidAppId": "ca-app-pub-....", "iosAppId": "ca-app-pub-...." } ], "expo-localization", [ "expo-location", { "locationAlwaysAndWhenInUsePermission": "Allow $(PRODUCT_NAME) to use your location." } ], [ "expo-image-picker", { "photosPermission": "Allow $(PRODUCT_NAME) to access your photos.", "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera." } ], [ "expo-sqlite", { "enableFTS": true, "useSQLCipher": true, "ios": { "customBuildFlags": ["-DSQLITE_ENABLE_DBSTAT_VTAB=1", "-DSQLITE_ENABLE_SNAPSHOT=1"] } } ], [ "expo-splash-screen", { "image": "./assets/images/splash-icon.png", "backgroundColor": "#0B4C6F", "resizeMode": "contain", "imageWidth": 200 } ], "expo-secure-store", "expo-background-task", "expo-web-browser", [ "expo-build-properties", { "ios": { "useFrameworks": "static", "deploymentTarget": "15.1" }, "android": { "minSdkVersion": 26 } } ], "./plugins/withAesGcmCrypto" ], "assetBundlePatterns": ["assets/**/*", "db/*.db"], "experiments": { "typedRoutes": true }, "extra": { "router": {}, "eas": { "projectId": "77c86bda-5768-4d5c-80a4-ff365269a374" } }, "owner": "mg83" } }ios/Podfile
android/build.gradle
android/app/build.gradle
android/settings.gradle
AndroidManifest.xml