react-native-google-mobile-ads 5.0.0 → 5.1.1
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.
- package/RNGoogleMobileAds.podspec +1 -1
- package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsConsentModule.java +19 -5
- package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsModule.java +1 -1
- package/docs/common-reasons-for-ads-not-showing.mdx +26 -24
- package/docs/displaying-ads-hook.mdx +99 -0
- package/docs/displaying-ads.mdx +3 -4
- package/docs/european-user-consent.mdx +34 -5
- package/docs/index.mdx +13 -13
- package/docs/migrating-to-v5.mdx +17 -8
- package/docs.json +2 -1
- package/ios/RNGoogleMobileAds/RNGoogleMobileAdsConsentModule.m +14 -0
- package/lib/commonjs/AdsConsent.js +47 -16
- package/lib/commonjs/AdsConsent.js.map +1 -1
- package/lib/commonjs/AdsConsentPurposes.js +47 -0
- package/lib/commonjs/AdsConsentPurposes.js.map +1 -0
- package/lib/commonjs/AdsConsentSpecialFeatures.js +39 -0
- package/lib/commonjs/AdsConsentSpecialFeatures.js.map +1 -0
- package/lib/commonjs/hooks/useAppOpenAd.js +51 -0
- package/lib/commonjs/hooks/useAppOpenAd.js.map +1 -0
- package/lib/commonjs/hooks/useFullScreenAd.js +120 -0
- package/lib/commonjs/hooks/useFullScreenAd.js.map +1 -0
- package/lib/commonjs/hooks/useInterstitialAd.js +51 -0
- package/lib/commonjs/hooks/useInterstitialAd.js.map +1 -0
- package/lib/commonjs/hooks/useRewardedAd.js +51 -0
- package/lib/commonjs/hooks/useRewardedAd.js.map +1 -0
- package/lib/commonjs/index.js +40 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types/AdStates.js +6 -0
- package/lib/commonjs/types/AdStates.js.map +1 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/commonjs/version.js.map +1 -1
- package/lib/module/AdsConsent.js +44 -16
- package/lib/module/AdsConsent.js.map +1 -1
- package/lib/module/AdsConsentPurposes.js +39 -0
- package/lib/module/AdsConsentPurposes.js.map +1 -0
- package/lib/module/AdsConsentSpecialFeatures.js +31 -0
- package/lib/module/AdsConsentSpecialFeatures.js.map +1 -0
- package/lib/module/hooks/useAppOpenAd.js +38 -0
- package/lib/module/hooks/useAppOpenAd.js.map +1 -0
- package/lib/module/hooks/useFullScreenAd.js +109 -0
- package/lib/module/hooks/useFullScreenAd.js.map +1 -0
- package/lib/module/hooks/useInterstitialAd.js +38 -0
- package/lib/module/hooks/useInterstitialAd.js.map +1 -0
- package/lib/module/hooks/useRewardedAd.js +38 -0
- package/lib/module/hooks/useRewardedAd.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/types/AdStates.js +2 -0
- package/lib/module/types/AdStates.js.map +1 -0
- package/lib/module/version.js +1 -1
- package/lib/module/version.js.map +1 -1
- package/lib/typescript/AdsConsentPurposes.d.ts +148 -0
- package/lib/typescript/AdsConsentSpecialFeatures.d.ts +22 -0
- package/lib/typescript/hooks/useAppOpenAd.d.ts +9 -0
- package/lib/typescript/hooks/useFullScreenAd.d.ts +5 -0
- package/lib/typescript/hooks/useInterstitialAd.d.ts +9 -0
- package/lib/typescript/hooks/useRewardedAd.d.ts +9 -0
- package/lib/typescript/index.d.ts +6 -1
- package/lib/typescript/types/AdStates.d.ts +85 -0
- package/lib/typescript/types/AdsConsent.interface.d.ts +216 -0
- package/lib/typescript/version.d.ts +1 -1
- package/package.json +6 -2
- package/src/AdsConsent.ts +75 -20
- package/src/AdsConsentPurposes.ts +182 -0
- package/src/AdsConsentSpecialFeatures.ts +48 -0
- package/src/hooks/useAppOpenAd.ts +46 -0
- package/src/hooks/useFullScreenAd.ts +104 -0
- package/src/hooks/useInterstitialAd.ts +46 -0
- package/src/hooks/useRewardedAd.ts +46 -0
- package/src/index.ts +5 -0
- package/src/types/AdStates.ts +87 -0
- package/src/types/AdsConsent.interface.ts +220 -0
- package/src/version.ts +1 -1
|
@@ -19,7 +19,7 @@ Pod::Spec.new do |s|
|
|
|
19
19
|
s.social_media_url = 'http://twitter.com/invertaseio'
|
|
20
20
|
s.ios.deployment_target = "10.0"
|
|
21
21
|
s.source_files = 'ios/**/*.{h,m}'
|
|
22
|
-
s.
|
|
22
|
+
s.weak_frameworks = "AppTrackingTransparency"
|
|
23
23
|
|
|
24
24
|
# React Native dependencies
|
|
25
25
|
s.dependency 'React-Core'
|
|
@@ -16,11 +16,13 @@ package io.invertase.googlemobileads;
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*
|
|
18
18
|
*/
|
|
19
|
-
|
|
19
|
+
import android.content.SharedPreferences;
|
|
20
|
+
import android.preference.PreferenceManager;
|
|
20
21
|
import com.facebook.react.bridge.Arguments;
|
|
21
22
|
import com.facebook.react.bridge.Promise;
|
|
22
23
|
import com.facebook.react.bridge.ReactApplicationContext;
|
|
23
24
|
import com.facebook.react.bridge.ReactMethod;
|
|
25
|
+
import com.facebook.react.bridge.ReadableArray;
|
|
24
26
|
import com.facebook.react.bridge.ReadableMap;
|
|
25
27
|
import com.facebook.react.bridge.WritableMap;
|
|
26
28
|
import com.google.android.ump.ConsentDebugSettings;
|
|
@@ -28,7 +30,6 @@ import com.google.android.ump.ConsentInformation;
|
|
|
28
30
|
import com.google.android.ump.ConsentRequestParameters;
|
|
29
31
|
import com.google.android.ump.UserMessagingPlatform;
|
|
30
32
|
import io.invertase.googlemobileads.common.ReactNativeModule;
|
|
31
|
-
import java.util.List;
|
|
32
33
|
import javax.annotation.Nonnull;
|
|
33
34
|
|
|
34
35
|
public class ReactNativeGoogleMobileAdsConsentModule extends ReactNativeModule {
|
|
@@ -63,10 +64,10 @@ public class ReactNativeGoogleMobileAdsConsentModule extends ReactNativeModule {
|
|
|
63
64
|
new ConsentDebugSettings.Builder(getApplicationContext());
|
|
64
65
|
|
|
65
66
|
if (options.hasKey("testDeviceIdentifiers")) {
|
|
66
|
-
|
|
67
|
+
ReadableArray devices = options.getArray("testDeviceIdentifiers");
|
|
67
68
|
|
|
68
|
-
for (
|
|
69
|
-
debugSettingsBuilder.addTestDeviceHashedId((
|
|
69
|
+
for (int i = 0; i < devices.size(); i++) {
|
|
70
|
+
debugSettingsBuilder.addTestDeviceHashedId(devices.getString(i));
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
73
|
|
|
@@ -152,4 +153,17 @@ public class ReactNativeGoogleMobileAdsConsentModule extends ReactNativeModule {
|
|
|
152
153
|
public void reset() {
|
|
153
154
|
consentInformation.reset();
|
|
154
155
|
}
|
|
156
|
+
|
|
157
|
+
@ReactMethod
|
|
158
|
+
public void getTCString(Promise promise) {
|
|
159
|
+
try {
|
|
160
|
+
SharedPreferences prefs =
|
|
161
|
+
PreferenceManager.getDefaultSharedPreferences(getReactApplicationContext());
|
|
162
|
+
// https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20CMP%20API%20v2.md#in-app-details
|
|
163
|
+
String tcString = prefs.getString("IABTCF_TCString", null);
|
|
164
|
+
promise.resolve(tcString);
|
|
165
|
+
} catch (Exception e) {
|
|
166
|
+
rejectPromiseWithCodeAndMessage(promise, "consent-string-error", e.toString());
|
|
167
|
+
}
|
|
168
|
+
}
|
|
155
169
|
}
|
package/android/src/main/java/io/invertase/googlemobileads/ReactNativeGoogleMobileAdsModule.java
CHANGED
|
@@ -117,7 +117,7 @@ public class ReactNativeGoogleMobileAdsModule extends ReactNativeModule {
|
|
|
117
117
|
@ReactMethod
|
|
118
118
|
public void initialize(Promise promise) {
|
|
119
119
|
MobileAds.initialize(
|
|
120
|
-
|
|
120
|
+
getApplicationContext(),
|
|
121
121
|
new OnInitializationCompleteListener() {
|
|
122
122
|
@Override
|
|
123
123
|
public void onInitializationComplete(InitializationStatus initializationStatus) {
|
|
@@ -13,6 +13,7 @@ You'll be notified of approval or rejection via email after review.
|
|
|
13
13
|
|
|
14
14
|
New apps and ad units take some time to activate.
|
|
15
15
|
Here are common reasons you may not see live impressions immediately:
|
|
16
|
+
|
|
16
17
|
- It usually takes at least an hour after you create an app or ad unit
|
|
17
18
|
- Sometimes it can take a few days for ads to appear in new apps or ad units
|
|
18
19
|
- New iOS apps will not show Google ads until they’re listed in the Apple App Store
|
|
@@ -35,6 +36,7 @@ Test devices can either be added in the AdMob UI or programmatically using the G
|
|
|
35
36
|
Follow the steps below to add your device as a test device.
|
|
36
37
|
|
|
37
38
|
#### Add your test device in the AdMob UI
|
|
39
|
+
|
|
38
40
|
For a simple, non-programmatic way to add a test device and test new or existing app builds, use the AdMob UI.
|
|
39
41
|
[Learn how](https://support.google.com/admob/answer/9691433).
|
|
40
42
|
|
|
@@ -48,39 +50,39 @@ If you want to test ads in your app as you're developing, follow the steps below
|
|
|
48
50
|
|
|
49
51
|
3. Check the console for a message that looks like this:
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
```
|
|
54
|
+
GADMobileAds.sharedInstance.requestConfiguration.testDeviceIdentifiers =
|
|
55
|
+
@[ @"2077ef9a63d2b398840261c8221a0c9b" ]; // Sample device ID
|
|
56
|
+
```
|
|
55
57
|
|
|
56
|
-
|
|
58
|
+
Copy your test device ID to your clipboard.
|
|
57
59
|
|
|
58
60
|
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
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
```
|
|
63
|
+
I/Ads: Use RequestConfiguration.Builder.setTestDeviceIds(Arrays.asList("33BE2250B43518CCDA7DE426D04EE231"))
|
|
64
|
+
to get test ads on this device."
|
|
65
|
+
```
|
|
64
66
|
|
|
65
|
-
|
|
67
|
+
Copy your test device ID to your clipboard.
|
|
66
68
|
|
|
67
69
|
5. Modify your code to set the test device ID through testDeviceIdentifiers
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
```js
|
|
72
|
+
import mobileAds from 'react-native-google-mobile-ads';
|
|
71
73
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
74
|
+
mobileAds()
|
|
75
|
+
.setRequestConfiguration({
|
|
76
|
+
// An array of test device IDs to add to the allow list.
|
|
77
|
+
testDeviceIdentifiers: ['2077ef9a63d2b398840261c8221a0c9b', 'EMULATOR'],
|
|
78
|
+
})
|
|
79
|
+
.then(() => {
|
|
80
|
+
// Request config successfully set!
|
|
81
|
+
});
|
|
82
|
+
```
|
|
81
83
|
|
|
82
|
-
|
|
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
|
+
6. 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.
|
|
85
|
+
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
86
|
|
|
85
87
|
## Emulator vs real device
|
|
86
88
|
|
|
@@ -89,4 +91,4 @@ In some cases ads won't show up on an emulator but will show up while testing on
|
|
|
89
91
|
## Extra links
|
|
90
92
|
|
|
91
93
|
- 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)
|
|
94
|
+
- [Common reasons for ads not showing](https://support.google.com/admob/answer/9469204)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Hooks
|
|
2
|
+
|
|
3
|
+
The AdMob package provides hooks to help you to display ads in a functional component with tiny code. The supported ad formats are full-screen ads: App open, Interstitial & Rewarded.
|
|
4
|
+
|
|
5
|
+
## Load an ad
|
|
6
|
+
|
|
7
|
+
You can create a new ad by adding a corresponding ad type's hook to your component.
|
|
8
|
+
|
|
9
|
+
The first argument of the hook is the "Ad Unit ID".
|
|
10
|
+
For testing, we can use a Test ID, however for production the ID from the
|
|
11
|
+
Google AdMob dashboard under "Ad units" should be used:
|
|
12
|
+
|
|
13
|
+
```tsx {4-8}
|
|
14
|
+
import { useInterstitialAd, TestIds } from 'react-native-google-mobile-ads';
|
|
15
|
+
|
|
16
|
+
export default function App() {
|
|
17
|
+
const interstitialAd = useInterstitialAd(TestIds.Interstitial, {
|
|
18
|
+
requestNonPersonalizedAdsOnly: true,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
return <View>{/* ... */}</View>;
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
> The `adUnitid` parameter can also be used to manage creation and destruction of an ad instance.
|
|
26
|
+
> If `adUnitid` is set or changed, new ad instance will be created and previous ad instance will be destroyed if exists.
|
|
27
|
+
> If `adUnitid` is set to `null`, no ad instance will be created and previous ad instance will be destroyed if exists.
|
|
28
|
+
|
|
29
|
+
The second argument is an additional optional request options object to be sent whilst loading an advert, such as keywords & location.
|
|
30
|
+
Setting additional request options helps AdMob choose better tailored ads from the network. View the [`RequestOptions`](/reference/admob/requestoptions)
|
|
31
|
+
documentation to view the full range of options available.
|
|
32
|
+
|
|
33
|
+
## Show the ad
|
|
34
|
+
|
|
35
|
+
The hook returns several states and functions to control ad.
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { useInterstitialAd, TestIds } from 'react-native-google-mobile-ads';
|
|
39
|
+
|
|
40
|
+
export default function App({ navigation }) {
|
|
41
|
+
const { isLoaded, isClosed, load, show } = useInterstitialAd(TestIds.Interstitial, {
|
|
42
|
+
requestNonPersonalizedAdsOnly: true,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
// Start loading the interstitial straight away
|
|
47
|
+
load();
|
|
48
|
+
}, [load]);
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (isClosed) {
|
|
52
|
+
// Action after the ad is closed
|
|
53
|
+
navigation.navigate('NextScreen');
|
|
54
|
+
}
|
|
55
|
+
}, [isClosed, navigation]);
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<View>
|
|
59
|
+
<Button
|
|
60
|
+
title="Navigate to next screen"
|
|
61
|
+
onPress={() => {
|
|
62
|
+
if (isLoaded) {
|
|
63
|
+
show();
|
|
64
|
+
} else {
|
|
65
|
+
// No advert ready to show yet
|
|
66
|
+
navigation.navigate('NextScreen');
|
|
67
|
+
}
|
|
68
|
+
}}
|
|
69
|
+
/>
|
|
70
|
+
</View>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The code above immediately starts to load a new advert from the network (via `load()`).
|
|
76
|
+
When user presses button, it checks if the ad is loaded via `isLoaded` value,
|
|
77
|
+
then the `show` function is called and the advert is shown over-the-top of your application.
|
|
78
|
+
Otherwise, if the ad is not loaded, the `navigation.navigate` method is called to navigate to the next screen without showing the ad.
|
|
79
|
+
After the ad is closed, the `isClosed` value is set to `true` and the `navigation.navigate` method is called to navigate to the next screen.
|
|
80
|
+
|
|
81
|
+
If needed, you can reuse the existing hook to load more adverts and show them when required. The states are initialized when the `load` function is called.
|
|
82
|
+
|
|
83
|
+
Return values of the hook are:
|
|
84
|
+
|
|
85
|
+
| Name | Type | Description |
|
|
86
|
+
| :------------- | :--------------------------------- | :----------------------------------------------------------------------------------------------------------------- |
|
|
87
|
+
| isLoaded | boolean | Whether the ad is loaded and ready to to be shown to the user. |
|
|
88
|
+
| isOpened | boolean | Whether the ad is opened. The value is remained `true` even after the ad is closed unless **new ad is requested**. |
|
|
89
|
+
| isClosed | boolean | Whether your ad is dismissed. |
|
|
90
|
+
| isShowing | boolean | Whether your ad is showing. The value is equal with `isOpened && !isClosed`. |
|
|
91
|
+
| error | Error \| undefined | `Error` object throwed during ad load. |
|
|
92
|
+
| reward | [RewardedAdReward](#) \| undefined | Loaded reward item of the Rewarded Ad. Available only in RewardedAd. |
|
|
93
|
+
| isEarnedReward | boolean | Whether the user earned the reward by Rewarded Ad. |
|
|
94
|
+
| load | Function | Start loading the advert with the provided RequestOptions. |
|
|
95
|
+
| show | Function | Show the loaded advert to the user. |
|
|
96
|
+
|
|
97
|
+
> Note that `isOpened` value remains `true` even after the ad is closed.
|
|
98
|
+
> The value changes to `false` when ad is initialized via calling `load()`.
|
|
99
|
+
> To determine whether the ad is currently showing, use `isShowing` value.
|
package/docs/displaying-ads.mdx
CHANGED
|
@@ -27,11 +27,10 @@ const appOpenAd = AppOpenAd.createForAdRequest(adUnitId, {
|
|
|
27
27
|
});
|
|
28
28
|
|
|
29
29
|
// Preload an app open ad
|
|
30
|
-
appOpenAd.load()
|
|
30
|
+
appOpenAd.load();
|
|
31
31
|
|
|
32
32
|
// Show the app open ad when user brings the app to the foreground.
|
|
33
|
-
appOpenAd.show()
|
|
34
|
-
|
|
33
|
+
appOpenAd.show();
|
|
35
34
|
```
|
|
36
35
|
|
|
37
36
|
### Consider ad expiration
|
|
@@ -159,7 +158,7 @@ The purpose of a rewarded ad is to reward users with _something_ after completin
|
|
|
159
158
|
as watching a video or submitting an option via an interactive form. If the user completes the action, you can reward them
|
|
160
159
|
with something (e.g. in-game currency).
|
|
161
160
|
|
|
162
|
-
To create a new
|
|
161
|
+
To create a new rewarded ad, call the `createForAdRequest` method from the `RewardedAd` class. The first argument
|
|
163
162
|
of the method is the "Ad Unit ID". For testing, we can use a Test ID, however for production the ID from the
|
|
164
163
|
Google AdMob dashboard under "Ad units" should be used:
|
|
165
164
|
|
|
@@ -93,16 +93,45 @@ import { AdsConsent, AdsConsentStatus } from 'react-native-google-mobile-ads';
|
|
|
93
93
|
|
|
94
94
|
const consentInfo = await AdsConsent.requestInfoUpdate();
|
|
95
95
|
|
|
96
|
-
if (
|
|
97
|
-
consentInfo.isConsentFormAvailable &&
|
|
98
|
-
consentInfo.status === AdsConsentStatus.REQUIRED
|
|
99
|
-
) {
|
|
96
|
+
if (consentInfo.isConsentFormAvailable && consentInfo.status === AdsConsentStatus.REQUIRED) {
|
|
100
97
|
const { status } = await AdsConsent.showForm();
|
|
101
98
|
}
|
|
102
99
|
```
|
|
103
100
|
|
|
104
101
|
> Do not persist the status. You could however store this locally in application state (e.g. React Context) and update the status on every app launch as it may change.
|
|
105
102
|
|
|
103
|
+
### Inspecting consent choices
|
|
104
|
+
|
|
105
|
+
The AdsConsentStatus tells you if you should show the modal to a user or not. Often times you want to run logic based on the user's choices though.
|
|
106
|
+
Especially since the Google Mobile Ads SDK won't show any ads if the user didn't give consent to store and/or access information on the device.
|
|
107
|
+
This library exports a method that returns some of the most relevant consent flags to handle common use cases.
|
|
108
|
+
|
|
109
|
+
```js
|
|
110
|
+
import { AdsConsent } from 'react-native-google-mobile-ads';
|
|
111
|
+
|
|
112
|
+
const {
|
|
113
|
+
activelyScanDeviceCharacteristicsForIdentification,
|
|
114
|
+
applyMarketResearchToGenerateAudienceInsights,
|
|
115
|
+
createAPersonalisedAdsProfile,
|
|
116
|
+
createAPersonalisedContentProfile,
|
|
117
|
+
developAndImproveProducts,
|
|
118
|
+
measureAdPerformance,
|
|
119
|
+
measureContentPerformance,
|
|
120
|
+
selectBasicAds,
|
|
121
|
+
selectPersonalisedAds,
|
|
122
|
+
selectPersonalisedContent,
|
|
123
|
+
storeAndAccessInformationOnDevice,
|
|
124
|
+
usePreciseGeolocationData,
|
|
125
|
+
} = await AdsConsent.getUserChoices();
|
|
126
|
+
|
|
127
|
+
if (storeAndAccessInformationOnDevice === false) {
|
|
128
|
+
/**
|
|
129
|
+
* The user declined consent for purpose 1,
|
|
130
|
+
* the Google Mobile Ads SDK won't serve ads.
|
|
131
|
+
*/
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
106
135
|
### Testing
|
|
107
136
|
|
|
108
137
|
When developing the consent flow, the behavior of the `AdsConsent` responses may not be reliable due to the environment
|
|
@@ -136,5 +165,5 @@ It is possible to reset the UMP state for test devices. To reset the ATT state y
|
|
|
136
165
|
```js
|
|
137
166
|
import { AdsConsent } from 'react-native-google-mobile-ads';
|
|
138
167
|
|
|
139
|
-
AdsConsent.reset()
|
|
168
|
+
AdsConsent.reset();
|
|
140
169
|
```
|
package/docs/index.mdx
CHANGED
|
@@ -7,21 +7,21 @@ yarn add react-native-google-mobile-ads
|
|
|
7
7
|
|
|
8
8
|
> On Android, before releasing your app, you must select _Yes, my app contains ads_ in the Google Play Store, Policy, App content, Manage under Ads.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## What does it do
|
|
11
11
|
|
|
12
12
|
The AdMob module allows you to display adverts to your users. All adverts are served over the Google AdMob network, meaning
|
|
13
13
|
a [Google AdMob account](https://apps.admob.com) is required.
|
|
14
14
|
|
|
15
15
|
<YouTube id="9qCxo0D-Sak" />
|
|
16
16
|
|
|
17
|
-
The module supports
|
|
17
|
+
The module supports four types of Ads:
|
|
18
18
|
|
|
19
19
|
1. Full screen [App Open Ads](/displaying-ads#app-open-ads).
|
|
20
20
|
2. Full screen [Interstitial Ads](/displaying-ads#interstitial-ads).
|
|
21
21
|
3. Full screen [Rewarded Ads](/displaying-ads#rewarded-ads).
|
|
22
22
|
4. Component based [Banner Ads](/displaying-ads#banner-ads).
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
## Getting Started
|
|
25
25
|
|
|
26
26
|
A number of steps must be taken and considered before you start serving adverts to your users:
|
|
27
27
|
|
|
@@ -33,7 +33,7 @@ A number of steps must be taken and considered before you start serving adverts
|
|
|
33
33
|
- [Test ads](#test-ads)
|
|
34
34
|
- [Next Steps](#next-steps)
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
### Setting up Google AdMob
|
|
37
37
|
|
|
38
38
|
Before you are able to display ads to your users, you must have a [Google AdMob account](https://apps.admob.com). Under the
|
|
39
39
|
"Apps" menu item, create or choose an existing Android/iOS app. Each app platform exposes a unique account ID which needs to
|
|
@@ -62,14 +62,14 @@ For the changes to take effect, rebuild your project:
|
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
64
|
# For iOS
|
|
65
|
-
|
|
65
|
+
npx pod-install
|
|
66
66
|
npx react-native run-ios
|
|
67
67
|
|
|
68
68
|
# For Android
|
|
69
69
|
npx react-native run-android
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
### Configure outbound requests
|
|
73
73
|
|
|
74
74
|
If the default ad settings are not correct for your app, you can provide settings that will apply to all ad requests.
|
|
75
75
|
|
|
@@ -94,7 +94,7 @@ mobileAds()
|
|
|
94
94
|
tagForUnderAgeOfConsent: true,
|
|
95
95
|
|
|
96
96
|
// An array of test device IDs to allow.
|
|
97
|
-
testDeviceIdentifiers: [
|
|
97
|
+
testDeviceIdentifiers: ['EMULATOR'],
|
|
98
98
|
})
|
|
99
99
|
.then(() => {
|
|
100
100
|
// Request config successfully set!
|
|
@@ -103,27 +103,27 @@ mobileAds()
|
|
|
103
103
|
|
|
104
104
|
To learn more about the request configuration settings, view the [`RequestConfiguration`](/reference/admob/requestconfiguration) documentation.
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
### Initialize the Google Mobile Ads SDK
|
|
107
107
|
|
|
108
108
|
Before loading ads, have your app initialize the Google Mobile Ads SDK by calling `initialize` which initializes the SDK and returns a promise once initialization is complete (or after a 30-second timeout).
|
|
109
109
|
This needs to be done only once, ideally at app launch.
|
|
110
110
|
|
|
111
111
|
> ⚠️ **Warning:** Ads may be preloaded by the Mobile Ads SDK or mediation partner SDKs upon calling `initialize`.
|
|
112
|
-
If you need to obtain consent from users in the European Economic Area (EEA), set any request-specific flags (such as tagForChildDirectedTreatment), or otherwise take action before loading ads, ensure you do so before initializing the Mobile Ads SDK.
|
|
112
|
+
> If you need to obtain consent from users in the European Economic Area (EEA), set any request-specific flags (such as tagForChildDirectedTreatment), or otherwise take action before loading ads, ensure you do so before initializing the Mobile Ads SDK.
|
|
113
113
|
|
|
114
114
|
```js
|
|
115
115
|
import mobileAds from 'react-native-google-mobile-ads';
|
|
116
116
|
|
|
117
117
|
mobileAds()
|
|
118
118
|
.initialize()
|
|
119
|
-
.then(
|
|
119
|
+
.then(adapterStatuses => {
|
|
120
120
|
// Initialization complete!
|
|
121
121
|
});
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
If you are using mediation, you may wish to wait until the promise is settled before loading ads, as this will ensure that all mediation adapters are initialized.
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
### European User Consent
|
|
127
127
|
|
|
128
128
|
Out of the box, AdMob does not handle any related regulations which you may need to enforce on your application.
|
|
129
129
|
It is up to the developer to implement and handle this on a user-by-user basis. You must consent to EEA users
|
|
@@ -133,7 +133,7 @@ being served both personalized and non-personalized adverts before showing them.
|
|
|
133
133
|
The AdMob module provides a `AdsConsent` helper to help developers quickly implement consent flows within their application.
|
|
134
134
|
See the [European User Consent page](/european-user-consent) for full examples of how to integrate the helper into your application.
|
|
135
135
|
|
|
136
|
-
|
|
136
|
+
### Test ads
|
|
137
137
|
|
|
138
138
|
Whilst developing your app with AdMob, you'll want to make sure you use test ads rather than production ads from your
|
|
139
139
|
Google AdMob account - otherwise your account may be disabled!
|
|
@@ -157,7 +157,7 @@ RewardedAd.createForAdRequest(TestIds.REWARDED);
|
|
|
157
157
|
<BannerAd unitId={TestIds.BANNER} />
|
|
158
158
|
```
|
|
159
159
|
|
|
160
|
-
|
|
160
|
+
## Next Steps
|
|
161
161
|
|
|
162
162
|
Now the basics of setting up and configuring AdMob have been explained, we can go ahead and start to display different
|
|
163
163
|
adverts to our users. The AdMob module provides integration with three different types:
|
package/docs/migrating-to-v5.mdx
CHANGED
|
@@ -13,13 +13,13 @@ Please refer to the following links for more information:
|
|
|
13
13
|
|
|
14
14
|
Previously it was possible to request the ad providers and to update the consent status. This is no longer the case.
|
|
15
15
|
Also, while the old Consent SDK provided information about user preferences, the new `AdsConsentStatus` only tells you if you should show the modal to a user or not.
|
|
16
|
-
You can read the `IABTCF_TCString` key from standardUserDefaults / SharedPreferences and decode it with a library like [@iabtcf/core](https://github.com/InteractiveAdvertisingBureau/iabtcf-es/tree/master/modules/core#iabtcfcore) though.
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
- `requestInfoUpdate` does now accept an optional `AdsConsentInfoOptions` object instead of expecting `publisherIds` and returns a changed `AdsConsentInfo` interface
|
|
18
|
+
- `showForm` does not expect any parameters any longer and now only returns the changed `AdsConsentStatus` as part of it's `AdsConsentFormResult` interface
|
|
19
|
+
- `getAdProviders`, `getStatus` and `setStatus` methods were removed without replacements
|
|
20
|
+
- `addTestDevices`, `setDebugGeography` and `setTagForUnderAgeOfConsent` methods were removed, but their functionality is available via `AdsConsentInfoOptions`
|
|
21
|
+
- the `user_tracking_usage_description` key is needed in your project's `app.json` if you want to handle Apple's App Tracking Transparency
|
|
22
|
+
- newly added `getUserChoices` can be used to inspect some of the consent choices
|
|
23
23
|
|
|
24
24
|
```diff
|
|
25
25
|
{
|
|
@@ -33,10 +33,10 @@ You can read the `IABTCF_TCString` key from standardUserDefaults / SharedPrefere
|
|
|
33
33
|
|
|
34
34
|
```diff
|
|
35
35
|
import { AdsConsent, AdsConsentStatus } from 'react-native-google-mobile-ads';
|
|
36
|
-
|
|
36
|
+
|
|
37
37
|
-const consentInfo = await AdsConsent.requestInfoUpdate(['pub-6189033257628123']);
|
|
38
38
|
+const consentInfo = await AdsConsent.requestInfoUpdate();
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
if (
|
|
41
41
|
- consentInfo.isRequestLocationInEeaOrUnknown &&
|
|
42
42
|
+ consentInfo.isConsentFormAvailable &&
|
|
@@ -50,5 +50,14 @@ You can read the `IABTCF_TCString` key from standardUserDefaults / SharedPrefere
|
|
|
50
50
|
- withAdFree: true,
|
|
51
51
|
- });
|
|
52
52
|
+ const formResult = await AdsConsent.showForm()
|
|
53
|
+
+
|
|
54
|
+
+ const { storeAndAccessInformationOnDevice } = await AdsConsent.getUserChoices();
|
|
55
|
+
+
|
|
56
|
+
+ if (storeAndAccessInformationOnDevice === false) {
|
|
57
|
+
+ /**
|
|
58
|
+
+ * The user declined consent for purpose 1,
|
|
59
|
+
+ * the Google Mobile Ads SDK won't serve ads.
|
|
60
|
+
+ */
|
|
61
|
+
+ }
|
|
53
62
|
}
|
|
54
63
|
```
|
package/docs.json
CHANGED
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
"sidebar": [
|
|
5
5
|
["Installation", "/"],
|
|
6
6
|
["Displaying Ads", "/displaying-ads"],
|
|
7
|
+
["Displaying Ads via Hook", "/displaying-ads-hook"],
|
|
7
8
|
["European User Consent", "/european-user-consent"],
|
|
8
9
|
["Common Reasons For Ads Not Showing", "/common-reasons-for-ads-not-showing"],
|
|
9
10
|
["Migrating to v5", "/migrating-to-v5"]
|
|
10
11
|
]
|
|
11
|
-
}
|
|
12
|
+
}
|
|
@@ -121,4 +121,18 @@ RCT_EXPORT_METHOD(showForm : (RCTPromiseResolveBlock)resolve : (RCTPromiseReject
|
|
|
121
121
|
|
|
122
122
|
RCT_EXPORT_METHOD(reset) { [UMPConsentInformation.sharedInstance reset]; }
|
|
123
123
|
|
|
124
|
+
RCT_EXPORT_METHOD(getTCString : (RCTPromiseResolveBlock)resolve : (RCTPromiseRejectBlock)reject) {
|
|
125
|
+
@try {
|
|
126
|
+
// https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/master/TCFv2/IAB%20Tech%20Lab%20-%20CMP%20API%20v2.md#in-app-details
|
|
127
|
+
NSString *tcString = [[NSUserDefaults standardUserDefaults] objectForKey:@"IABTCF_TCString"];
|
|
128
|
+
resolve(tcString);
|
|
129
|
+
} @catch (NSError *error) {
|
|
130
|
+
[RNSharedUtils rejectPromiseWithUserInfo:reject
|
|
131
|
+
userInfo:[@{
|
|
132
|
+
@"code" : @"consent-string-error",
|
|
133
|
+
@"message" : error.localizedDescription,
|
|
134
|
+
} mutableCopy]];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
124
138
|
@end
|
|
@@ -5,12 +5,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.AdsConsent = void 0;
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _core = require("@iabtcf/core");
|
|
9
9
|
|
|
10
10
|
var _reactNative = require("react-native");
|
|
11
11
|
|
|
12
12
|
var _AdsConsentDebugGeography = require("./AdsConsentDebugGeography");
|
|
13
13
|
|
|
14
|
+
var _AdsConsentPurposes = require("./AdsConsentPurposes");
|
|
15
|
+
|
|
16
|
+
var _AdsConsentSpecialFeatures = require("./AdsConsentSpecialFeatures");
|
|
17
|
+
|
|
18
|
+
var _common = require("./common");
|
|
19
|
+
|
|
14
20
|
/*
|
|
15
21
|
* Copyright (c) 2016-present Invertase Limited & Contributors
|
|
16
22
|
*
|
|
@@ -29,14 +35,6 @@ var _AdsConsentDebugGeography = require("./AdsConsentDebugGeography");
|
|
|
29
35
|
*/
|
|
30
36
|
const native = _reactNative.NativeModules.RNGoogleMobileAdsConsentModule;
|
|
31
37
|
const AdsConsent = {
|
|
32
|
-
/**
|
|
33
|
-
*
|
|
34
|
-
* @param {Object} [options]
|
|
35
|
-
* @param {AdsConsentDebugGeography} [options.debugGeography]
|
|
36
|
-
* @param {Boolean} [options.tagForUnderAgeOfConsent]
|
|
37
|
-
* @param {Array<String>} [options.testDeviceIdentifiers]
|
|
38
|
-
* @returns {{ status: Number, isConsentFormAvailable: Boolean }}
|
|
39
|
-
*/
|
|
40
38
|
requestInfoUpdate() {
|
|
41
39
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
42
40
|
|
|
@@ -69,19 +67,52 @@ const AdsConsent = {
|
|
|
69
67
|
return native.requestInfoUpdate(options);
|
|
70
68
|
},
|
|
71
69
|
|
|
72
|
-
/**
|
|
73
|
-
*
|
|
74
|
-
* @returns {{ status: Number }}
|
|
75
|
-
*/
|
|
76
70
|
showForm() {
|
|
77
71
|
return native.showForm();
|
|
78
72
|
},
|
|
79
73
|
|
|
80
|
-
/**
|
|
81
|
-
*
|
|
82
|
-
*/
|
|
83
74
|
reset() {
|
|
84
75
|
return native.reset();
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
getTCString() {
|
|
79
|
+
return native.getTCString();
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
async getTCModel() {
|
|
83
|
+
const tcString = await native.getTCString();
|
|
84
|
+
return _core.TCString.decode(tcString);
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
async getUserChoices() {
|
|
88
|
+
const tcString = await native.getTCString();
|
|
89
|
+
let tcModel;
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
tcModel = _core.TCString.decode(tcString);
|
|
93
|
+
} catch (e) {
|
|
94
|
+
tcModel = new _core.TCModel();
|
|
95
|
+
|
|
96
|
+
if (__DEV__) {
|
|
97
|
+
// eslint-disable-next-line no-console
|
|
98
|
+
console.warn(`Failed to decode tcString ${tcString}:`, e);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
activelyScanDeviceCharacteristicsForIdentification: tcModel.specialFeatureOptins.has(_AdsConsentSpecialFeatures.AdsConsentSpecialFeatures.ACTIVELY_SCAN_DEVICE_CHARACTERISTICS_FOR_IDENTIFICATION),
|
|
104
|
+
applyMarketResearchToGenerateAudienceInsights: tcModel.purposeConsents.has(_AdsConsentPurposes.AdsConsentPurposes.APPLY_MARKET_RESEARCH_TO_GENERATE_AUDIENCE_INSIGHTS),
|
|
105
|
+
createAPersonalisedAdsProfile: tcModel.purposeConsents.has(_AdsConsentPurposes.AdsConsentPurposes.CREATE_A_PERSONALISED_ADS_PROFILE),
|
|
106
|
+
createAPersonalisedContentProfile: tcModel.purposeConsents.has(_AdsConsentPurposes.AdsConsentPurposes.CREATE_A_PERSONALISED_ADS_PROFILE),
|
|
107
|
+
developAndImproveProducts: tcModel.purposeConsents.has(_AdsConsentPurposes.AdsConsentPurposes.DEVELOP_AND_IMPROVE_PRODUCTS),
|
|
108
|
+
measureAdPerformance: tcModel.purposeConsents.has(_AdsConsentPurposes.AdsConsentPurposes.MEASURE_AD_PERFORMANCE),
|
|
109
|
+
measureContentPerformance: tcModel.purposeConsents.has(_AdsConsentPurposes.AdsConsentPurposes.MEASURE_CONTENT_PERFORMANCE),
|
|
110
|
+
selectBasicAds: tcModel.purposeConsents.has(_AdsConsentPurposes.AdsConsentPurposes.SELECT_BASIC_ADS),
|
|
111
|
+
selectPersonalisedAds: tcModel.purposeConsents.has(_AdsConsentPurposes.AdsConsentPurposes.SELECT_PERSONALISED_ADS),
|
|
112
|
+
selectPersonalisedContent: tcModel.purposeConsents.has(_AdsConsentPurposes.AdsConsentPurposes.SELECT_PERSONALISED_CONTENT),
|
|
113
|
+
storeAndAccessInformationOnDevice: tcModel.purposeConsents.has(_AdsConsentPurposes.AdsConsentPurposes.STORE_AND_ACCESS_INFORMATION_ON_DEVICE),
|
|
114
|
+
usePreciseGeolocationData: tcModel.specialFeatureOptins.has(_AdsConsentSpecialFeatures.AdsConsentSpecialFeatures.USE_PRECISE_GEOLOCATION_DATA)
|
|
115
|
+
};
|
|
85
116
|
}
|
|
86
117
|
|
|
87
118
|
};
|