Closed Arekjaar4 closed 2 years ago
Hi there! With apologies, I've got no idea because there are no details or steps to reproduce https://stackoverflow.com/help/mcve
In this case steps to reproduce would start from an expo init I suppose, and then list the further commands you run, contents of any config files you change, finishing with the build failure
Hi,
Thanks for the answer.
This is a code that reproduces the error: https://github.com/Arekjaar4/testads
please describe how it was built and the commands to run in order to demonstrate the error
start from an expo init I suppose, and then list the further commands you run, contents of any config files you change, finishing with the build failure
expo start I use the Expo app to test
Perhaps you add the module somehow? You don't have to specify iOS or anything ? I don't use Expo Please write the steps exactly as I requested, as if for a grade school student
I have the same issue, I create a project with expo init,
and don't matter if I chose a minimal blank project or a bare one. Next, I install yarn add react-native-google-mobile-ads
like the documentation, and add the "react-native-google-mobile-ads": { "android_app_id": "ca-app-pub-xxxxxxxx~xxxxxxxx", "ios_app_id": "ca-app-pub-xxxxxxxx~xxxxxxxx" }
in the root of app.json. Finally, when import the import {BannerAd, TestIds } from 'react-native-google-mobile-ads <BannerAd unitId={TestIds.BANNER} />'
into my app.js, I receive this error message
Invariant Violation: requireNativeComponent: "RNGoogleMobileAdsBannerView" was not found in the UIManager.
Note: I haven't tried in ios, just my android, and I use my Admob ID.
@Harreson-Lima I am about to do the same thing, from a managed workflow. Did you build your project using the EAS feature? Bare or managed?
@mikehardy I think that, in order to migrate to this package, from expo, we will have to make a build using EAS.
When we simply run expo init
the CLI ask us if we want to create our project using the managed workflow (only JS, no native code) or the bare one (JS + native code). Here you can read about workflows.
So, I suppose that, as I can read in the Expo documentation for expo-ads-admob
This module will be removed in SDK 46. There will be no replacement that works with the classic build service (expo build) because the classic build service has been superseded by EAS Build. With EAS Build and Development Builds, you should use react-native-google-mobile-ads instead.
we will need to build our app, or at least, move to the bare workflow in order to play with this module (not really sure, but I suppose this library is not compatible with the managed workflow).
So, @Arekjaar4 @Harreson-Lima running expo prebuild
could be an option.
indeed, it will be EAS only as far as I know. There is no way for the Expo GO / managed client to have our native code, and our native code is essential to the functioning of the app. Going bare could also work, if you install the module after ejecting.
If any one could propose a doc update to state very very explicitly in Expo docs that you should use this module with EAS build or bare workflow that would probably help reduce confusion as apparently we're going to have a lot of new Expo users soon...
@VictorioMolina I haven't used the EAS feature, but i tried the bare workflow and don't work
I am also migrating from expo-ads-admob, and I have a working expo project with all my ads code commented out and built with EAS build. I then run npm install react-native-google-mobile-ads
, add the ad IDs to my app.json, and run the EAS build again. Trying to launch the resulting app on iOS crashes immediately, and I don't get any error messages or anything. This is without even importing the library in my code yet. So really the only difference is the presence of the library.
I'll try to work on getting a minimum reproducible example to share, but wondering if anyone else has gotten it to work yet or if its just me? I posted on Expo forums too and no response yet.
@mikehardy I'll migrate my project to the EAS feature now. I'm a newbie in react native, to be honest, thank you.
I'll be building my project using EAS in a few weeks (1/2), so I can't be very explicit about the process at this point (I haven't tested it). But if by then you haven't found another solution, in case I'm lucky, I'll try to explain you the migration steps in detail.
I'll try to use this documentation to migrate https://docs.expo.dev/build-reference/migrating/ if I've news I come back to inform you all.
I am also migrating from expo-ads-admob, and I have a working expo project with all my ads code commented out and built with EAS build. I then run
npm install react-native-google-mobile-ads
, add the ad IDs to my app.json, and run the EAS build again. Trying to launch the resulting app on iOS crashes immediately, and I don't get any error messages or anything. This is without even importing the library in my code yet. So really the only difference is the presence of the library. I'll try to work on getting a minimum reproducible example to share, but wondering if anyone else has gotten it to work yet or if its just me? I posted on Expo forums too and no response yet.
If ti crashes on startup, that is almost certainly a missing admob id (the app output if you run it from xcode or if you watch it in Console.app will show the exception so you can be sure) - the chain of events that needs to happen for the admob id to be present in a way the native SDK sees it on startup is:
Something in that chain of events is not happening and if you search for Info.plist file in the build output directory and examine it you will probably not see the admob id, but if you run our example app you should see it. Something sort of expo specific will be in the mix here
Thanks for the detailed info, definitely helps point me in a direction to look into more! I created a new expo app from scratch and added the library, and it doesn't crash. I looked at the built info.plist files for both and sure enough the new app has a GADApplicationIdentifier key with the admob id whereas my original app doesn't. That said, I'm not sure where it's going wrong. Here is an excerpt from my original app.json that crashes:
{
"expo": {
...
},
"react-native-google-mobile-ads": {
"android_app_id": "ca-app-pub-[X]",
"ios_app_id": "ca-app-pub-[Y]"
}
}
I examined the build logs and while I'm not really sure what I'm looking for I do see this which might indicate it's doing something with RNGoogleMobileAds and info.plist?
› Preparing Scoot » Info.plist
› Executing Scoot » Bundle React Native code and images
the transform cache was reset.
› Generating debug Scoot » Scoot.app.dSYM
› Executing Scoot » [CP] Copy Pods Resources
› Executing Scoot » Upload Debug Symbols to Sentry
› Executing Scoot » [CP-User] [RNGoogleMobileAds] Configuration
› Signing Scoot » Scoot.app
› Creating Scoot » Scoot.app
› Archive Succeeded
Does anything stand out as being amiss, or is there any other information I could provide that might help?
› Executing Scoot » [CP-User] [RNGoogleMobileAds] Configuration
That's our run script added by our react-native-config.js as a pod step, and it should be calling ios-config.sh (I think, going from memory sorry - but the code's all in the repo ;-) )
That does look right, in your app.json. Maybe the first project is missing the config plugin entry? I'm really not sure - I'm sorry - but I'm gratified to know it's at least possible, creating a fresh app via expo and seeing it work is encouraging as it shows it should be working :thinking:
I can't recommend this as a general solution, but you can of course just add the ID in your Info.plist. All of this config machinery is suppose to keep things "react-native style" by letting you just drop it in an app.json and poof all the native stuff hooks up, but really it's just to copy the plist info in. You can just set it and be unblocked for now while further investigation happens at a lower priority for you
This is the error displayed when trying to create the apk with the following command: eas build -p android --profile preview
[stderr] /home/expo/workingdir/build/android/app/src/main/AndroidManifest.xml:22:85-105 Error:
[stderr] Attribute meta-data#com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT@value value=(true) from AndroidManifest.xml:22:85-105
[stderr] is also present at [:react-native-google-mobile-ads] AndroidManifest.xml:19:13-34 value=(false).
[stderr] Suggestion: add 'tools:replace="android:value"' to
I just added in the android_app_id key to the app.json of my fresh new expo app and built it, and it is working also. So I tried it with my original app on android and that is also working. So now it is just my original iOS app that is not working for me due to the missing keys in info.plist. But now that it's been narrowed down to that part of the build, I will move over to expo forums to see if they can help figure out that part. @mikehardy thanks for your assistance and responsiveness! (also I can't really manually update info.plist without ejecting to expo's bare workflow, so will keep trucking on to solve this for now).
I just added in the android_app_id key to the app.json of my fresh new expo app and built it, and it is working also. So I tried it with my original app on android and that is also working. So now it is just my original iOS app that is not working for me due to the missing keys in info.plist. But now that it's been narrowed down to that part of the build, I will move over to expo forums to see if they can help figure out that part. @mikehardy thanks for your assistance and responsiveness! (also I can't really manually update info.plist without ejecting to expo's bare workflow, so will keep trucking on to solve this for now).
You can show your app.json to see how you have added the android_app_id?
{
"expo": {
"name": "my-app",
"slug": "my-app",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.duggster.myapp"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#FFFFFF"
},
"package": "com.duggster.myapp"
},
"web": {
"favicon": "./assets/favicon.png"
}
},
"react-native-google-mobile-ads": {
"android_app_id": "ca-app-pub-1234567890123456~1234567890",
"ios_app_id": "ca-app-pub-1234567890123456~1234567890"
}
}
also I can't really manually update info.plist without ejecting to expo's bare workflow, so will keep trucking on to solve this for now)
I think (sorry if wrong) that Expo EAS in their config already has a way to add plist entries as part of prebuild? You might be able to use that? I'm just trying to think of workarounds for you so you are not blocked, but I have to say my summary of the situation at the moment is "the module appears to be working on fresh projects, and most existing projects" so I am not currently thinking of this as actionable here, but I'm listening in case any new experiment results invalidate that current stance
Good luck - I hope it resolves
@mikehardy indeed expo does have a way to inject plist entries in app.json, I forgot about that and actually expo uses that as a way to specify the different permissions messages. Here is mine:
"infoPlist": {
"NSLocationWhenInUseUsageDescription": "Allow app to use location for the purpose of loading weather conditions at the user's location.",
"NSPhotoLibraryUsageDescription": "Allow app to use photos to be able to set a background image and images for each family member.",
"NSCalendarsUsageDescription": "Allow Scoot to show your iOS calendar events in this view. You can disable this later in your Scoot Settings if desired.",
"NSRemindersUsageDescription": "Allow app to integrate your iOS reminder events in with Scoot calendar events.",
"NSUserTrackingUsageDescription": "This will be used to deliver personalized ads to you.",
"NSContactsUsageDescription": "Allow app to access your contacts so you can send event reminders to them."
}
Turns out one of the strings I have there appears to be causing the issue because of an apostrophe. I received some pointers from expo forums that led me to this error in the xcode build logs:
info: -> RNGoogleMobileAds build script started
info: 1) Locating app.json file:
info: (1 of 2) Searching in '/Users/expo/workingdir/build' for a app.json file.
info: app.json found at /Users/expo/workingdir/build/app.json
-e:47: syntax error, unexpected local variable or method, expecting ')'
...eather conditions at the user's location.",
... ^
-e:47: syntax error, unexpected string literal
...itions at the user's location.",
... ^
-e:48: syntax error, unexpected constant, expecting end-of-input
..."NSPhotoLibraryUsageDescription": "Allow app to use photos t...
... ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
info: 2) Injecting Info.plist entries:
-> 0) google_mobile_ads_json_raw string e30=
info: setting plist entry 'google_mobile_ads_json_raw' of type 'string' in file '/Users/expo/Library/Developer/Xcode/DerivedData/Scoot-dxafajfnmudobohdoabbyjtwdhpq/Build/Intermediates.noindex/ArchiveIntermediates/Scoot/BuildProductsPath/Debug-iphoneos/Scoot.app/Info.plist'
info: setting plist entry 'google_mobile_ads_json_raw' of type 'string' in file '/Users/expo/Library/Developer/Xcode/DerivedData/Scoot-dxafajfnmudobohdoabbyjtwdhpq/Build/Intermediates.noindex/ArchiveIntermediates/Scoot/BuildProductsPath/Debug-iphoneos/Scoot.app.dSYM/Contents/Info.plist'
info: <- RNGoogleMobileAds build script finished
Is this something you can adjust in the script so apostrophes don't throw an error? I'm not sure if I should have escaped that apostrophe or not, but if it happened to me I'm sure it could happen to others too.
Hmm - well that's definitely invalid JSON so it looks like what you have actually done is find two bugs at once:
1) your project seems like it had a bug before this, with invalid app.json, that was sliding through somehow? 2) our validation and error handling in the ios config script needs to fail fast, it's the silent replacement with '{}' (that's what e30= is, after base64) is a disaster here as a dev experience
I won't have time to make the defensive programming patch here but the enhancement is, I think:
1) don't just parse and silently fail, in this module the file must exist because the app id is required, so if the parsing is about to return e30= for _JSON_OUTPUT_RAW print out a huge ASCII-art style error message and exit 1
2) the file is not optional in this module (it was in react-native-firebase), so if the file is not found, also print out a huge error message and exit 1 (probably abstract to a "print huge error message and exit 1" method and just call it with the message
3) app id is not optional, so the if here needs an else and a huge error message + exit 1 if the app id is not found in app.json:
Quick note about the solution in the new title, it's OK to use Expo managed workflow (I am), but you just cannot use the Expo Go app to run it and you need to build a dev-client using the EAS build process. Could be something more like "must use eas build dev-client or bare workflow"
Hello,
I was able to fix the error with the command "expo prebuild" In my case I have also had to modify this line in the AndroidManifest Attribute meta-data#com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT@value value=(true) to Attribute meta-data#com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT@value value=(false) To make it work with IOS you need to uninstall the "expo-ads-admob" library
Thank you all for your contributions.
Greetings.
I'm using the app.config.js file to load my values from env, but in the console I got the error:
Error: Problem validating fields in app.json. Learn more: https://docs.expo.dev/workflow/configuration/ • should NOT have additional property 'react-native-android-mobile-ads'.
Do you have an idea how to solve it?
I'm not even aware of what app.config.js is. You may want to approach expo forums for support on this one It's my understanding that app.json is "configuration by convention" and expo should tolerate literally any valid JSON in there, as they use the file but do not own the file.
Hello,
I managed to solve my problem and I was able to do the migration. I explain everything I did in this Medium article:
@Arekjaar4 Do you also a solution for app.config.js configuration?
@Arekjaar4 Do you also a solution for app.config.js configuration?
no, sorry
@julste my dynamic config file is working fine, just set ads keys outside expo prop
app.config.ts
import { ExpoConfig, ConfigContext } from '@expo/config';
// https://docs.expo.io/versions/latest/config/app/
const VERSION_CODE = 5;
const RELEASE_DATE = new Date().toISOString().split('T')[0];
const APP_PACKAGE_NAME = 'com.mypackage.app';
type AppConfig = {
expo: ExpoConfig;
[key: string]: any;
};
const appConfig: AppConfig = {
'react-native-google-mobile-ads': {
android_app_id: 'ca-app-pub-xxxx',
ios_app_id: 'ca-app-pub-xxxx',
delay_app_measurement_init: false,
user_tracking_usage_description: 'This identifier will be used to deliver personalized ads to you.'
},
'expo': {
name: 'My App',
slug: 'my-app',
scheme: APP_PACKAGE_NAME,
description: 'test',
privacy: 'public',
version: `${VERSION_CODE}_${RELEASE_DATE}`,
jsEngine: 'hermes',
orientation: 'default',
icon: './assets/app-icon.png',
splash: {
image: './assets/app-splash-screen.png',
resizeMode: 'contain',
backgroundColor: '#7159c1',
},
...
},
};
export default appConfig;
@allandiego Using your suggestion doesn't seem to work when building on EAS. I get the error that android_app_id
cannot be found. Have you tried this with EAS? I have been trying to find a way to get the dynamic app config working with this package but haven't had any luck.
Hi @DavidBriglio , here's how I did it to get it work with EAS for the purpose of building an app variant:
app.json
{
"react-native-google-mobile-ads": {
"android_app_id": "ca-app-pub-XXXX",
"ios_app_id": "ca-app-pub-YYYY"
}
}
app.config.js
const APP_VARIANT = process.env.APP_VARIANT;
const IS_DEV = APP_VARIANT === 'dev';
export default {
expo: {
....everything else
}
}
The expo docs describe how to use app.json
and app.config.js
at the same time. Make sure the react-native-google-mobile-ads
block is in app.json
since app.config.js
is an expo feature and not a react-native-google-mobile-ads feature.
It basically works like this:
app.json
{
"expo": {
"name": "My App"
},
"react-native-google-mobile-ads": {
"android_app_id": "ca-app-pub-XXXX",
"ios_app_id": "ca-app-pub-YYYY"
}
}
app.config.js
module.exports = ({ config }) => {
console.log(config.name); // prints 'My App'
return {
// Here is the place to merge your dynamic config with your static app.json config
...config,
};
};
Thank you @duggster and @DoctorJohn, these work well. Where I got tripped up was adding my app.json
file to my .gitignore
so that I could avoid adding my admob ids into version control. Since that file was in the ignore, it was not sent to EAS in the build, and that was causing the undefined android_app_id
error.
My solution is adding app.json
to the .git/info/exclude
file instead. It will prevent changes from being committed to version control, but still be included in the EAS build since it is not in the .gitignore
file.
I am migrating from expo-ads-admob to react-native-google-mobile-ads but when testing the app I get the following error: Invariant Violation: requireNativeComponent: "RNGoogleMobileAdsBannerView" was not found in the UIManager.
Do you know why this error occurs and how to fix it?