react-native-google-mobile-ads 4.1.2 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/RNGoogleMobileAds.podspec +16 -9
  2. package/__tests__/consent.test.ts +17 -9
  3. package/android/build.gradle +4 -3
  4. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsAppOpenModule.java +2 -5
  5. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsCommon.java +13 -2
  6. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsConsentModule.java +100 -171
  7. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsInterstitialModule.java +6 -5
  8. package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsRewardedModule.java +3 -4
  9. package/docs/common-reasons-for-ads-not-showing.mdx +92 -0
  10. package/docs/european-user-consent.mdx +43 -161
  11. package/docs/index.mdx +3 -3
  12. package/docs/migrating-to-v5.mdx +54 -0
  13. package/docs.json +3 -1
  14. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsAppOpenModule.m +1 -2
  15. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsCommon.h +1 -1
  16. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsCommon.m +6 -2
  17. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsConsentModule.h +0 -1
  18. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsConsentModule.m +71 -126
  19. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsInterstitialModule.m +1 -2
  20. package/ios/RNGoogleMobileAds/RNGoogleMobileAdsRewardedModule.m +1 -2
  21. package/ios_config.sh +8 -0
  22. package/lib/commonjs/AdsConsent.js +29 -100
  23. package/lib/commonjs/AdsConsent.js.map +1 -1
  24. package/lib/commonjs/AdsConsentStatus.js +4 -3
  25. package/lib/commonjs/AdsConsentStatus.js.map +1 -1
  26. package/lib/commonjs/validateAdRequestOptions.js +8 -0
  27. package/lib/commonjs/validateAdRequestOptions.js.map +1 -1
  28. package/lib/commonjs/version.js +1 -1
  29. package/lib/commonjs/version.js.map +1 -1
  30. package/lib/module/AdsConsent.js +30 -100
  31. package/lib/module/AdsConsent.js.map +1 -1
  32. package/lib/module/AdsConsentStatus.js +4 -3
  33. package/lib/module/AdsConsentStatus.js.map +1 -1
  34. package/lib/module/validateAdRequestOptions.js +8 -0
  35. package/lib/module/validateAdRequestOptions.js.map +1 -1
  36. package/lib/module/version.js +1 -1
  37. package/lib/module/version.js.map +1 -1
  38. package/lib/typescript/AdsConsentStatus.d.ts +10 -6
  39. package/lib/typescript/index.d.ts +1 -1
  40. package/lib/typescript/types/AdsConsent.interface.d.ts +37 -204
  41. package/lib/typescript/types/RequestOptions.d.ts +8 -0
  42. package/lib/typescript/version.d.ts +1 -1
  43. package/package.json +5 -3
  44. package/src/AdsConsent.ts +36 -135
  45. package/src/AdsConsentStatus.ts +11 -6
  46. package/src/types/AdsConsent.interface.ts +37 -214
  47. package/src/types/RequestOptions.ts +7 -0
  48. package/src/validateAdRequestOptions.ts +7 -0
  49. package/src/version.ts +1 -1
@@ -1,7 +1,8 @@
1
1
  require 'json'
2
2
  package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
3
3
 
4
- google_ads_sdk_version = package['sdkVersions']['ios']['googleAds']
4
+ google_mobile_ads_sdk_version = package['sdkVersions']['ios']['googleMobileAds']
5
+ google_ump_sdk_version = package['sdkVersions']['ios']['googleUmp']
5
6
 
6
7
  Pod::Spec.new do |s|
7
8
  s.name = "RNGoogleMobileAds"
@@ -18,24 +19,30 @@ Pod::Spec.new do |s|
18
19
  s.social_media_url = 'http://twitter.com/invertaseio'
19
20
  s.ios.deployment_target = "10.0"
20
21
  s.source_files = 'ios/**/*.{h,m}'
22
+ s.frameworks = "AppTrackingTransparency"
21
23
 
22
24
  # React Native dependencies
23
25
  s.dependency 'React-Core'
24
26
 
25
27
  # Other dependencies
26
- s.dependency 'PersonalizedAdConsent', '~> 1.0.5'
28
+ if defined?($RNGoogleUmpSDKVersion)
29
+ Pod::UI.puts "#{s.name}: Using user specified Google UMP SDK version '#{$RNGoogleUmpSDKVersion}'"
30
+ google_ump_sdk_version = $RNGoogleUmpSDKVersion
31
+ end
32
+
33
+ s.dependency 'GoogleUserMessagingPlatform', google_ump_sdk_version
27
34
 
28
- if defined?($RNGoogleAdsSDKVersion)
29
- Pod::UI.puts "#{s.name}: Using user specified Google Mobile-Ads SDK version '#{$RNGoogleAdsSDKVersion}'"
30
- google_ads_sdk_version = $RNGoogleAdsSDKVersion
35
+ if defined?($RNGoogleMobileAdsSDKVersion)
36
+ Pod::UI.puts "#{s.name}: Using user specified Google Mobile-Ads SDK version '#{$RNGoogleMobileAdsSDKVersion}'"
37
+ google_mobile_ads_sdk_version = $RNGoogleMobileAdsSDKVersion
31
38
  end
32
39
 
33
40
  # AdMob dependencies
34
- s.dependency 'Google-Mobile-Ads-SDK', google_ads_sdk_version
41
+ s.dependency 'Google-Mobile-Ads-SDK', google_mobile_ads_sdk_version
35
42
 
36
- if defined?($RNGoogleAdsAsStaticFramework)
37
- Pod::UI.puts "#{s.name}: Using overridden static_framework value of '#{$RNGoogleAdsAsStaticFramework}'"
38
- s.static_framework = $RNGoogleAdsAsStaticFramework
43
+ if defined?($RNGoogleMobileAdsAsStaticFramework)
44
+ Pod::UI.puts "#{s.name}: Using overridden static_framework value of '#{$RNGoogleMobileAdsAsStaticFramework}'"
45
+ s.static_framework = $RNGoogleMobileAdsAsStaticFramework
39
46
  else
40
47
  s.static_framework = false
41
48
  end
@@ -2,23 +2,31 @@ import { AdsConsent } from '../src';
2
2
 
3
3
  describe('Google Mobile Ads AdsConsent', function () {
4
4
  describe('requestInfoUpdate', function () {
5
- it('throws if publisherIds is not an array', function () {
5
+ it('throws if options are not an object', function () {
6
6
  // @ts-ignore
7
- expect(() => AdsConsent.requestInfoUpdate('pub-123')).toThrowError(
8
- "AdsConsent.requestInfoUpdate(*) 'publisherIds' expected an array of string values.",
7
+ expect(() => AdsConsent.requestInfoUpdate('123')).toThrowError(
8
+ "AdsConsent.requestInfoUpdate(*) 'options' expected an object value.",
9
9
  );
10
10
  });
11
11
 
12
- it('throws if publisherIds is empty array', function () {
13
- expect(() => AdsConsent.requestInfoUpdate([])).toThrowError(
14
- "AdsConsent.requestInfoUpdate(*) 'publisherIds' list of publisher IDs cannot be empty.",
12
+ it('throws if options.debugGeography is not a valid value.', function () {
13
+ // @ts-ignore
14
+ expect(() => AdsConsent.requestInfoUpdate({ debugGeography: -1 })).toThrowError(
15
+ "AdsConsent.requestInfoUpdate(*) 'options.debugGeography' expected one of AdsConsentDebugGeography.DISABLED, AdsConsentDebugGeography.EEA or AdsConsentDebugGeography.NOT_EEA.",
16
+ );
17
+ });
18
+
19
+ it('throws if options.tagForUnderAgeOfConsent is not a boolean.', function () {
20
+ // @ts-ignore
21
+ expect(() => AdsConsent.requestInfoUpdate({ tagForUnderAgeOfConsent: '123' })).toThrowError(
22
+ "AdsConsent.requestInfoUpdate(*) 'options.tagForUnderAgeOfConsent' expected a boolean value.",
15
23
  );
16
24
  });
17
25
 
18
- it('throws if publisherIds contains non-string values', function () {
26
+ it('throws if options.testDeviceIdentifiers is not an array', function () {
19
27
  // @ts-ignore
20
- expect(() => AdsConsent.requestInfoUpdate(['foo', 123])).toThrowError(
21
- "AdsConsent.requestInfoUpdate(*) 'publisherIds[1]' expected a string value.",
28
+ expect(() => AdsConsent.requestInfoUpdate({ testDeviceIdentifiers: '123' })).toThrowError(
29
+ "AdsConsent.requestInfoUpdate(*) 'options.testDeviceIdentifiers' expected an array of string values.",
22
30
  );
23
31
  });
24
32
  });
@@ -22,6 +22,7 @@ plugins {
22
22
 
23
23
  def packageJson = PackageJson.getForProject(project)
24
24
  def googleMobileAdsVersion = packageJson['sdkVersions']['android']['googleMobileAds']
25
+ def googleUmpVersion = packageJson['sdkVersions']['android']['googleUmp']
25
26
  def jsonMinSdk = packageJson['sdkVersions']['android']['minSdk']
26
27
  def jsonTargetSdk = packageJson['sdkVersions']['android']['targetSdk']
27
28
  def jsonCompileSdk = packageJson['sdkVersions']['android']['compileSdk']
@@ -44,7 +45,7 @@ project.ext {
44
45
  ],
45
46
 
46
47
  ads : [
47
- consent: "1.0.6"
48
+ consent: googleUmpVersion,
48
49
  ],
49
50
  ],
50
51
  ])
@@ -88,8 +89,8 @@ repositories {
88
89
  }
89
90
 
90
91
  dependencies {
91
- implementation("com.google.android.gms:play-services-ads:20.5.0") { force = true; }
92
- implementation "com.google.android.ads.consent:consent-library:${ReactNative.ext.getVersion("ads", "consent")}"
92
+ implementation("com.google.android.gms:play-services-ads:${googleMobileAdsVersion}") { force = true; }
93
+ api "com.google.android.ump:user-messaging-platform:${googleUmpVersion}"
93
94
  }
94
95
 
95
96
  ReactNative.shared.applyPackageVersion()
@@ -17,6 +17,7 @@ package io.invertase.googlemobileads;
17
17
  *
18
18
  */
19
19
 
20
+ import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsCommon.buildAdRequest;
20
21
  import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsCommon.getCodeAndMessageFromAdError;
21
22
  import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsCommon.sendAdEvent;
22
23
  import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsEvent.GOOGLE_MOBILE_ADS_EVENT_APP_OPEN;
@@ -34,7 +35,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
34
35
  import com.facebook.react.bridge.ReactMethod;
35
36
  import com.facebook.react.bridge.ReadableMap;
36
37
  import com.facebook.react.bridge.WritableMap;
37
- import com.google.android.gms.ads.AdRequest;
38
38
  import com.google.android.gms.ads.FullScreenContentCallback;
39
39
  import com.google.android.gms.ads.LoadAdError;
40
40
  import com.google.android.gms.ads.appopen.AppOpenAd;
@@ -67,9 +67,6 @@ public class ReactNativeGoogleMobileAdsAppOpenModule extends ReactNativeModule {
67
67
  }
68
68
  currentActivity.runOnUiThread(
69
69
  () -> {
70
- AdRequest.Builder adRequestBuilder = new AdRequest.Builder();
71
- AdRequest adRequest = adRequestBuilder.build();
72
-
73
70
  AppOpenAd.AppOpenAdLoadCallback appOpenAdLoadCallback =
74
71
  new AppOpenAd.AppOpenAdLoadCallback() {
75
72
 
@@ -115,7 +112,7 @@ public class ReactNativeGoogleMobileAdsAppOpenModule extends ReactNativeModule {
115
112
  AppOpenAd.load(
116
113
  currentActivity,
117
114
  adUnitId,
118
- adRequest,
115
+ buildAdRequest(adRequestOptions),
119
116
  AppOpenAd.APP_OPEN_AD_ORIENTATION_PORTRAIT,
120
117
  appOpenAdLoadCallback);
121
118
  });
@@ -31,6 +31,7 @@ import com.google.ads.mediation.admob.AdMobAdapter;
31
31
  import com.google.android.gms.ads.AdError;
32
32
  import com.google.android.gms.ads.AdRequest;
33
33
  import com.google.android.gms.ads.AdSize;
34
+ import com.google.android.gms.ads.admanager.AdManagerAdRequest;
34
35
  import io.invertase.googlemobileads.common.ReactNativeEventEmitter;
35
36
  import java.util.ArrayList;
36
37
  import java.util.Map;
@@ -130,8 +131,8 @@ public class ReactNativeGoogleMobileAdsCommon {
130
131
  return map;
131
132
  }
132
133
 
133
- public static AdRequest buildAdRequest(ReadableMap adRequestOptions) {
134
- AdRequest.Builder builder = new AdRequest.Builder();
134
+ public static AdManagerAdRequest buildAdRequest(ReadableMap adRequestOptions) {
135
+ AdManagerAdRequest.Builder builder = new AdManagerAdRequest.Builder();
135
136
  Bundle extras = new Bundle();
136
137
 
137
138
  if (adRequestOptions.hasKey("requestNonPersonalizedAdsOnly")
@@ -177,6 +178,16 @@ public class ReactNativeGoogleMobileAdsCommon {
177
178
  builder.setRequestAgent(Objects.requireNonNull(adRequestOptions.getString("requestAgent")));
178
179
  }
179
180
 
181
+ if (adRequestOptions.hasKey("customTargeting")) {
182
+ Map<String, Object> customTargeting = adRequestOptions.getMap("customTargeting").toHashMap();
183
+
184
+ for (Map.Entry<String, Object> entry : customTargeting.entrySet()) {
185
+ String key = entry.getKey();
186
+ String value = (String) entry.getValue();
187
+ builder.addCustomTargeting(key, value);
188
+ }
189
+ }
190
+
180
191
  return builder.build();
181
192
  }
182
193
 
@@ -21,206 +21,135 @@ import com.facebook.react.bridge.Arguments;
21
21
  import com.facebook.react.bridge.Promise;
22
22
  import com.facebook.react.bridge.ReactApplicationContext;
23
23
  import com.facebook.react.bridge.ReactMethod;
24
- import com.facebook.react.bridge.ReadableArray;
25
24
  import com.facebook.react.bridge.ReadableMap;
26
- import com.facebook.react.bridge.WritableArray;
27
25
  import com.facebook.react.bridge.WritableMap;
28
- import com.google.ads.consent.AdProvider;
29
- import com.google.ads.consent.ConsentForm;
30
- import com.google.ads.consent.ConsentFormListener;
31
- import com.google.ads.consent.ConsentInfoUpdateListener;
32
- import com.google.ads.consent.ConsentInformation;
33
- import com.google.ads.consent.ConsentStatus;
34
- import com.google.ads.consent.DebugGeography;
26
+ import com.google.android.ump.ConsentDebugSettings;
27
+ import com.google.android.ump.ConsentInformation;
28
+ import com.google.android.ump.ConsentRequestParameters;
29
+ import com.google.android.ump.UserMessagingPlatform;
35
30
  import io.invertase.googlemobileads.common.ReactNativeModule;
36
- import java.net.MalformedURLException;
37
- import java.net.URL;
38
31
  import java.util.List;
32
+ import javax.annotation.Nonnull;
39
33
 
40
34
  public class ReactNativeGoogleMobileAdsConsentModule extends ReactNativeModule {
35
+
41
36
  private static final String TAG = "RNGoogleMobileAdsConsentModule";
42
37
  private ConsentInformation consentInformation;
43
- private ConsentForm consentForm;
44
38
 
45
39
  public ReactNativeGoogleMobileAdsConsentModule(ReactApplicationContext reactContext) {
46
40
  super(reactContext, TAG);
47
- consentInformation = ConsentInformation.getInstance(reactContext);
41
+ consentInformation = UserMessagingPlatform.getConsentInformation(reactContext);
48
42
  }
49
43
 
50
- private int getConsentStatusInt(ConsentStatus consentStatus) {
44
+ private String getConsentStatusString(int consentStatus) {
51
45
  switch (consentStatus) {
52
- case NON_PERSONALIZED:
53
- return 1;
54
- case PERSONALIZED:
55
- return 2;
56
- case UNKNOWN:
46
+ case ConsentInformation.ConsentStatus.REQUIRED:
47
+ return "REQUIRED";
48
+ case ConsentInformation.ConsentStatus.NOT_REQUIRED:
49
+ return "NOT_REQUIRED";
50
+ case ConsentInformation.ConsentStatus.OBTAINED:
51
+ return "OBTAINED";
52
+ case ConsentInformation.ConsentStatus.UNKNOWN:
57
53
  default:
58
- return 0;
54
+ return "UNKNOWN";
59
55
  }
60
56
  }
61
57
 
62
58
  @ReactMethod
63
- public void requestInfoUpdate(ReadableArray publisherIds, Promise promise) {
64
- @SuppressWarnings("SuspiciousToArrayCall")
65
- String[] publisherIdsArray = publisherIds.toArrayList().toArray(new String[0]);
66
-
67
- consentInformation.requestConsentInfoUpdate(
68
- publisherIdsArray,
69
- new ConsentInfoUpdateListener() {
70
- @Override
71
- public void onConsentInfoUpdated(ConsentStatus consentStatus) {
59
+ public void requestInfoUpdate(@Nonnull final ReadableMap options, final Promise promise) {
60
+ try {
61
+ ConsentRequestParameters.Builder paramsBuilder = new ConsentRequestParameters.Builder();
62
+ ConsentDebugSettings.Builder debugSettingsBuilder =
63
+ new ConsentDebugSettings.Builder(getApplicationContext());
64
+
65
+ if (options.hasKey("testDeviceIdentifiers")) {
66
+ List<Object> devices = options.getArray("testDeviceIdentifiers").toArrayList();
67
+
68
+ for (Object device : devices) {
69
+ debugSettingsBuilder.addTestDeviceHashedId((String) device);
70
+ }
71
+ }
72
+
73
+ if (options.hasKey("debugGeography")) {
74
+ debugSettingsBuilder.setDebugGeography(options.getInt("debugGeography"));
75
+ }
76
+
77
+ paramsBuilder.setConsentDebugSettings(debugSettingsBuilder.build());
78
+
79
+ if (options.hasKey("tagForUnderAgeOfConsent")) {
80
+ paramsBuilder.setTagForUnderAgeOfConsent(options.getBoolean("tagForUnderAgeOfConsent"));
81
+ }
82
+
83
+ ConsentRequestParameters consentRequestParameters = paramsBuilder.build();
84
+
85
+ if (getCurrentActivity() == null) {
86
+ rejectPromiseWithCodeAndMessage(
87
+ promise,
88
+ "null-activity",
89
+ "Attempted to request a consent info update but the current Activity was null.");
90
+ return;
91
+ }
92
+
93
+ consentInformation.requestConsentInfoUpdate(
94
+ getCurrentActivity(),
95
+ consentRequestParameters,
96
+ () -> {
72
97
  WritableMap requestInfoMap = Arguments.createMap();
73
- requestInfoMap.putInt("status", getConsentStatusInt(consentStatus));
98
+ requestInfoMap.putString(
99
+ "status", getConsentStatusString(consentInformation.getConsentStatus()));
74
100
  requestInfoMap.putBoolean(
75
- "isRequestLocationInEeaOrUnknown",
76
- consentInformation.isRequestLocationInEeaOrUnknown());
101
+ "isConsentFormAvailable", consentInformation.isConsentFormAvailable());
77
102
  promise.resolve(requestInfoMap);
78
- }
79
-
80
- @Override
81
- public void onFailedToUpdateConsentInfo(String reason) {
82
- rejectPromiseWithCodeAndMessage(promise, "consent-update-failed", reason);
83
- }
84
- });
85
- }
86
-
87
- @ReactMethod
88
- public void showForm(ReadableMap options, Promise promise) {
89
- if (getCurrentActivity() == null) {
90
- rejectPromiseWithCodeAndMessage(
91
- promise,
92
- "null-activity",
93
- "Consent form attempted to show but the current Activity was null.");
94
- return;
103
+ },
104
+ formError ->
105
+ rejectPromiseWithCodeAndMessage(
106
+ promise, "consent-update-failed", formError.getMessage()));
107
+ } catch (Exception e) {
108
+ rejectPromiseWithCodeAndMessage(promise, "consent-update-failed", e.toString());
95
109
  }
96
- getCurrentActivity()
97
- .runOnUiThread(
98
- () -> {
99
- URL privacyUrl = null;
100
-
101
- try {
102
- privacyUrl = new URL(options.getString("privacyPolicy"));
103
- } catch (MalformedURLException e) {
104
- // Validated in JS land
105
- }
106
-
107
- ConsentFormListener listener =
108
- new ConsentFormListener() {
109
- @Override
110
- public void onConsentFormLoaded() {
111
- try {
112
- consentForm.show();
113
- } catch (Exception e) {
114
- rejectPromiseWithCodeAndMessage(
115
- promise, "consent-form-error", e.toString());
116
- }
117
- }
118
-
119
- @Override
120
- public void onConsentFormClosed(
121
- ConsentStatus consentStatus, Boolean userPrefersAdFree) {
122
- WritableMap consentFormMap = Arguments.createMap();
123
- consentFormMap.putInt("status", getConsentStatusInt(consentStatus));
124
- consentFormMap.putBoolean("userPrefersAdFree", userPrefersAdFree);
125
- promise.resolve(consentFormMap);
126
- }
127
-
128
- @Override
129
- public void onConsentFormError(String reason) {
130
- rejectPromiseWithCodeAndMessage(promise, "consent-form-error", reason);
131
- }
132
- };
133
-
134
- ConsentForm.Builder builder =
135
- new ConsentForm.Builder(getCurrentActivity(), privacyUrl).withListener(listener);
136
-
137
- if (options.hasKey("withPersonalizedAds")
138
- && options.getBoolean("withPersonalizedAds")) {
139
- builder = builder.withPersonalizedAdsOption();
140
- }
141
-
142
- if (options.hasKey("withNonPersonalizedAds")
143
- && options.getBoolean("withNonPersonalizedAds")) {
144
- builder = builder.withNonPersonalizedAdsOption();
145
- }
146
-
147
- if (options.hasKey("withAdFree") && options.getBoolean("withAdFree")) {
148
- builder = builder.withAdFreeOption();
149
- }
150
-
151
- consentForm = builder.build();
152
- consentForm.load();
153
- });
154
110
  }
155
111
 
156
112
  @ReactMethod
157
- public void getStatus(Promise promise) {
158
- ConsentStatus status = consentInformation.getConsentStatus();
159
- promise.resolve(getConsentStatusInt(status));
160
- }
161
-
162
- @ReactMethod
163
- public void setStatus(int status, Promise promise) {
164
- ConsentStatus consentStatus = ConsentStatus.UNKNOWN;
165
-
166
- switch (status) {
167
- case 0:
168
- consentStatus = ConsentStatus.UNKNOWN;
169
- break;
170
- case 1:
171
- consentStatus = ConsentStatus.NON_PERSONALIZED;
172
- break;
173
- case 2:
174
- consentStatus = ConsentStatus.PERSONALIZED;
175
- break;
113
+ public void showForm(final Promise promise) {
114
+ try {
115
+ if (getCurrentActivity() == null) {
116
+ rejectPromiseWithCodeAndMessage(
117
+ promise,
118
+ "null-activity",
119
+ "Consent form attempted to show but the current Activity was null.");
120
+ return;
121
+ }
122
+ getCurrentActivity()
123
+ .runOnUiThread(
124
+ () ->
125
+ UserMessagingPlatform.loadConsentForm(
126
+ getReactApplicationContext(),
127
+ consentForm ->
128
+ consentForm.show(
129
+ getCurrentActivity(),
130
+ formError -> {
131
+ if (formError != null) {
132
+ rejectPromiseWithCodeAndMessage(
133
+ promise, "consent-form-error", formError.getMessage());
134
+ } else {
135
+ WritableMap consentFormMap = Arguments.createMap();
136
+ consentFormMap.putString(
137
+ "status",
138
+ getConsentStatusString(
139
+ consentInformation.getConsentStatus()));
140
+ promise.resolve(consentFormMap);
141
+ }
142
+ }),
143
+ formError ->
144
+ rejectPromiseWithCodeAndMessage(
145
+ promise, "consent-form-error", formError.getMessage())));
146
+ } catch (Exception e) {
147
+ rejectPromiseWithCodeAndMessage(promise, "consent-form-error", e.toString());
176
148
  }
177
-
178
- consentInformation.setConsentStatus(consentStatus);
179
- promise.resolve(null);
180
149
  }
181
150
 
182
151
  @ReactMethod
183
- public void getAdProviders(Promise promise) {
184
- List<AdProvider> providers = consentInformation.getAdProviders();
185
-
186
- WritableArray formattedAdProviders = Arguments.createArray();
187
-
188
- for (AdProvider provider : providers) {
189
- WritableMap formattedProvider = Arguments.createMap();
190
- formattedProvider.putString("companyName", provider.getName());
191
- formattedProvider.putString("companyId", provider.getId());
192
- formattedProvider.putString("privacyPolicyUrl", provider.getPrivacyPolicyUrlString());
193
- formattedAdProviders.pushMap(formattedProvider);
194
- }
195
-
196
- promise.resolve(formattedAdProviders);
197
- }
198
-
199
- @ReactMethod
200
- public void setTagForUnderAgeOfConsent(boolean tag, Promise promise) {
201
- consentInformation.setTagForUnderAgeOfConsent(tag);
202
- promise.resolve(null);
203
- }
204
-
205
- @ReactMethod
206
- public void setDebugGeography(int geography, Promise promise) {
207
- if (geography == 0) {
208
- consentInformation.setDebugGeography(DebugGeography.DEBUG_GEOGRAPHY_DISABLED);
209
- } else if (geography == 1) {
210
- consentInformation.setDebugGeography(DebugGeography.DEBUG_GEOGRAPHY_EEA);
211
- } else if (geography == 2) {
212
- consentInformation.setDebugGeography(DebugGeography.DEBUG_GEOGRAPHY_NOT_EEA);
213
- }
214
-
215
- promise.resolve(null);
216
- }
217
-
218
- @ReactMethod
219
- public void addTestDevices(ReadableArray deviceIds, Promise promise) {
220
- List<Object> devices = deviceIds.toArrayList();
221
- for (Object device : devices) {
222
- consentInformation.addTestDevice((String) device);
223
- }
224
- promise.resolve(null);
152
+ public void reset() {
153
+ consentInformation.reset();
225
154
  }
226
155
  }
@@ -17,6 +17,7 @@ package io.invertase.googlemobileads;
17
17
  *
18
18
  */
19
19
 
20
+ import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsCommon.buildAdRequest;
20
21
  import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsCommon.getCodeAndMessageFromAdError;
21
22
  import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsCommon.sendAdEvent;
22
23
  import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsEvent.GOOGLE_MOBILE_ADS_EVENT_CLICKED;
@@ -35,7 +36,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
35
36
  import com.facebook.react.bridge.ReactMethod;
36
37
  import com.facebook.react.bridge.ReadableMap;
37
38
  import com.facebook.react.bridge.WritableMap;
38
- import com.google.android.gms.ads.AdRequest;
39
39
  import com.google.android.gms.ads.FullScreenContentCallback;
40
40
  import com.google.android.gms.ads.LoadAdError;
41
41
  import com.google.android.gms.ads.interstitial.InterstitialAd;
@@ -69,9 +69,6 @@ public class ReactNativeGoogleMobileAdsInterstitialModule extends ReactNativeMod
69
69
  }
70
70
  currentActivity.runOnUiThread(
71
71
  () -> {
72
- AdRequest.Builder adRequestBuilder = new AdRequest.Builder();
73
- AdRequest adRequest = adRequestBuilder.build();
74
-
75
72
  InterstitialAdLoadCallback interstitialAdLoadCallback =
76
73
  new InterstitialAdLoadCallback() {
77
74
 
@@ -114,7 +111,11 @@ public class ReactNativeGoogleMobileAdsInterstitialModule extends ReactNativeMod
114
111
  }
115
112
  };
116
113
 
117
- InterstitialAd.load(currentActivity, adUnitId, adRequest, interstitialAdLoadCallback);
114
+ InterstitialAd.load(
115
+ currentActivity,
116
+ adUnitId,
117
+ buildAdRequest(adRequestOptions),
118
+ interstitialAdLoadCallback);
118
119
  });
119
120
  }
120
121
 
@@ -1,5 +1,6 @@
1
1
  package io.invertase.googlemobileads;
2
2
 
3
+ import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsCommon.buildAdRequest;
3
4
  import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsCommon.getCodeAndMessageFromAdError;
4
5
  import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsCommon.sendAdEvent;
5
6
  import static io.invertase.googlemobileads.ReactNativeGoogleMobileAdsEvent.GOOGLE_MOBILE_ADS_EVENT_CLOSED;
@@ -18,7 +19,6 @@ import com.facebook.react.bridge.ReactApplicationContext;
18
19
  import com.facebook.react.bridge.ReactMethod;
19
20
  import com.facebook.react.bridge.ReadableMap;
20
21
  import com.facebook.react.bridge.WritableMap;
21
- import com.google.android.gms.ads.AdRequest;
22
22
  import com.google.android.gms.ads.FullScreenContentCallback;
23
23
  import com.google.android.gms.ads.LoadAdError;
24
24
  import com.google.android.gms.ads.OnUserEarnedRewardListener;
@@ -64,8 +64,6 @@ public class ReactNativeGoogleMobileAdsRewardedModule extends ReactNativeModule
64
64
  }
65
65
  activity.runOnUiThread(
66
66
  () -> {
67
- AdRequest adRequest = new AdRequest.Builder().build();
68
-
69
67
  RewardedAdLoadCallback rewardedAdLoadCallback =
70
68
  new RewardedAdLoadCallback() {
71
69
  @Override
@@ -129,7 +127,8 @@ public class ReactNativeGoogleMobileAdsRewardedModule extends ReactNativeModule
129
127
  }
130
128
  };
131
129
 
132
- RewardedAd.load(activity, adUnitId, adRequest, rewardedAdLoadCallback);
130
+ RewardedAd.load(
131
+ activity, adUnitId, buildAdRequest(adRequestOptions), rewardedAdLoadCallback);
133
132
  });
134
133
  }
135
134
 
@@ -0,0 +1,92 @@
1
+ # Common reasons for ads not showing
2
+
3
+ Use the following guide to understand common reasons why apps show few or no ads.
4
+
5
+ ## Did you recently create your AdMob account?
6
+
7
+ Your account must be approved before ad requests will succeed.
8
+ When you first sign up for AdMob, your account is reviewed before it’s approved.
9
+ This typically takes less than 24 hours, but in rare cases can take up to 2 weeks.
10
+ You'll be notified of approval or rejection via email after review.
11
+
12
+ ## Is your app or ad unit new?
13
+
14
+ New apps and ad units take some time to activate.
15
+ Here are common reasons you may not see live impressions immediately:
16
+ - It usually takes at least an hour after you create an app or ad unit
17
+ - Sometimes it can take a few days for ads to appear in new apps or ad units
18
+ - New iOS apps will not show Google ads until they’re listed in the Apple App Store
19
+
20
+ ## Test ads not showing up
21
+
22
+ If you set up an app-ads.txt file for your app, you need to also include this line in your app-ads.txt file in order to load ads using the demo ad units:
23
+ `google.com, pub-3940256099942544, DIRECT, f08c47fec0942fa0`
24
+
25
+ - Set up app-ads.txt [iOS](https://developers.google.com/admob/ios/app-ads), [Android](https://developers.google.com/admob/android/app-ads)
26
+ - Enabling test ads [iOS](https://developers.google.com/admob/ios/test-ads), [Android](https://developers.google.com/admob/android/test-ads)
27
+
28
+ Alternatively, you can enable test devices and use your own ad unit IDs instead.
29
+
30
+ ### Enable test devices
31
+
32
+ If you want to do more rigorous testing with production-looking ads, configure your device as a test device and use your own ad unit IDs that you've created in the AdMob UI.
33
+ Test devices can either be added in the AdMob UI or programmatically using the Google Mobile Ads SDK.
34
+
35
+ Follow the steps below to add your device as a test device.
36
+
37
+ #### Add your test device in the AdMob UI
38
+ For a simple, non-programmatic way to add a test device and test new or existing app builds, use the AdMob UI.
39
+ [Learn how](https://support.google.com/admob/answer/9691433).
40
+
41
+ #### Add your test device programmatically
42
+
43
+ If you want to test ads in your app as you're developing, follow the steps below to programmatically register your test device.
44
+
45
+ 1. Load your ads-integrated app and make an ad request.
46
+
47
+ 2. For **iOS** follow step 3, for **Android** skip to step 4.
48
+
49
+ 3. Check the console for a message that looks like this:
50
+
51
+ ```
52
+ GADMobileAds.sharedInstance.requestConfiguration.testDeviceIdentifiers =
53
+ @[ @"2077ef9a63d2b398840261c8221a0c9b" ]; // Sample device ID
54
+ ```
55
+
56
+ Copy your test device ID to your clipboard.
57
+
58
+ 4. Check the logcat output for a message that looks like the one below, which shows you your device ID and how to add it as a test device:
59
+
60
+ ```
61
+ I/Ads: Use RequestConfiguration.Builder.setTestDeviceIds(Arrays.asList("33BE2250B43518CCDA7DE426D04EE231"))
62
+ to get test ads on this device."
63
+ ```
64
+
65
+ Copy your test device ID to your clipboard.
66
+
67
+ 5. Modify your code to set the test device ID through testDeviceIdentifiers
68
+
69
+ ```js
70
+ import mobileAds from 'react-native-google-mobile-ads';
71
+
72
+ mobileAds()
73
+ .setRequestConfiguration({
74
+ // An array of test device IDs to add to the allow list.
75
+ testDeviceIdentifiers: ["2077ef9a63d2b398840261c8221a0c9b", "EMULATOR"]
76
+ })
77
+ .then(() => {
78
+ // Request config successfully set!
79
+ });
80
+ ```
81
+
82
+ 5. Re-run your app. If the ad is a Google ad, you'll see a Test Ad label centered at the top of the ad.
83
+ Ads with this Test Ad label are safe to click. Requests, impressions, and clicks on test ads will not show up in your account's reports.
84
+
85
+ ## Emulator vs real device
86
+
87
+ In some cases ads won't show up on an emulator but will show up while testing on a real device.
88
+
89
+ ## Extra links
90
+
91
+ - Mobile Ads SDK [iOS](https://developers.google.com/admob/ios/quick-start), [Android](https://developers.google.com/admob/android/quick-start)
92
+ - [Common reasons for ads not showing](https://support.google.com/admob/answer/9469204)