@react-native-google-mobile-ads/facebook 17.2.0 → 17.3.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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Meta Audience Network (Facebook) **Google Ad Manager / AdMob mediation** adapter package for [`react-native-google-mobile-ads`](https://github.com/invertase/react-native-google-mobile-ads).
4
4
 
5
- This package links Google’s official Meta Audience Network mediation adapter on Android and iOS. It does **not** ship AppLovin MAX, CloudX, or any JS ad APIs — use core `initialize()` / adapter status for discovery.
5
+ This package links Google’s official Meta Audience Network mediation adapter on Android and iOS. It does **not** ship AppLovin MAX, CloudX, or JS ad-format APIs — use core `initialize()` / adapter status for discovery. It **does** expose Meta privacy hooks that must run before GMA initialize.
6
6
 
7
7
  ## Install
8
8
 
@@ -13,6 +13,42 @@ yarn add @react-native-google-mobile-ads/facebook
13
13
 
14
14
  Autolinking pulls in the native mediation artifacts. Rebuild the app after install.
15
15
 
16
+ ## Advertiser tracking (call before `initialize`)
17
+
18
+ On **iOS versions below 17**, Meta’s Audience Network expects advertiser tracking to be set **before**
19
+ Google Mobile Ads initialize. After App Tracking Transparency resolves (when you use it), call:
20
+
21
+ ```ts
22
+ import mobileAds from 'react-native-google-mobile-ads';
23
+ import { setAdvertiserTrackingEnabled } from '@react-native-google-mobile-ads/facebook';
24
+
25
+ // After ATT (e.g. expo-tracking-transparency) resolves:
26
+ setAdvertiserTrackingEnabled(true); // or false when tracking is denied
27
+ await mobileAds().initialize();
28
+ ```
29
+
30
+ | Platform | Behavior |
31
+ | -------- | -------- |
32
+ | iOS | Calls `FBAdSettings.setAdvertiserTrackingEnabled`. On **iOS 17+** with Audience Network **6.15.0+**, Meta marks this setter deprecated and unused — the SDK uses `ATTrackingManager.trackingAuthorizationStatus` instead (verified from local `FBAdSettings.h` in FBAudienceNetwork 6.17.1 / 6.22.0). |
33
+ | Android | No-op — Meta’s Android `AdSettings` (audience-network-sdk 6.22.0) has no advertiser-tracking setter |
34
+
35
+ Optional Limited Data Use / data-processing options:
36
+
37
+ ```ts
38
+ import { setDataProcessingOptions } from '@react-native-google-mobile-ads/facebook';
39
+
40
+ setDataProcessingOptions(['LDU']);
41
+ // or with geography:
42
+ setDataProcessingOptions(['LDU'], /* country */ 1, /* state */ 1000);
43
+ ```
44
+
45
+ | Platform | Behavior |
46
+ | -------- | -------- |
47
+ | Android | `AdSettings.setDataProcessingOptions` |
48
+ | iOS | `FBAdSettings.setDataProcessingOptions` |
49
+
50
+ These are **runtime JS APIs**, not Expo plugin keys. Passing `metaAdvertiserTrackingEnabled` (or similar) to the core or facebook Expo plugin is ignored with a warning.
51
+
16
52
  ## Native adapter class names (GAM / AdMob UI)
17
53
 
18
54
  | Platform | Class name |
@@ -33,7 +69,7 @@ import {
33
69
 
34
70
  | Platform | Coordinate | Version pin |
35
71
  | -------- | ---------- | ----------- |
36
- | Android | `com.google.ads.mediation:facebook` | `6.22.0.0` |
72
+ | Android | `com.google.ads.mediation:facebook` | `6.22.0.1` |
37
73
  | iOS | CocoaPods `GoogleMobileAdsMediationFacebook` | `6.22.0.0` |
38
74
 
39
75
  Citations (verify at upgrade time):
@@ -61,10 +97,28 @@ Platform floors align with core: iOS **15.1** and Android minSdk **24**. The Met
61
97
  ]
62
98
  ```
63
99
 
64
- App IDs stay in the core Expo plugin.
100
+ App IDs stay in the core Expo plugin. Advertiser tracking stays in JS (`setAdvertiserTrackingEnabled`) — ATT status is not knowable at prebuild time.
101
+
102
+ ## iOS launch abort when this adapter is linked
103
+
104
+ `GoogleMobileAdsMediationFacebook` embeds Meta’s `FBAudienceNetwork`. That framework can `SIGABRT` during
105
+ its own early main-queue `dispatch_once` work — **before any ad request and before JS**. One reported
106
+ exception reason is an unrecognized selector involving format string `%s` on `NSString`.
107
+
108
+ That is **not** a bug in this package’s `RNGoogleMobileAdsAdapterFacebook` bridge (those methods only run
109
+ when JS calls them). This package’s `setAdvertiserTrackingEnabled` / `setDataProcessingOptions` helpers
110
+ therefore cannot prevent a process-start abort inside Meta’s binary.
111
+
112
+ Checklist when only Meta mediation crashes at launch (AppLovin / Unity OK):
113
+
114
+ 1. AdMob / GAM `GADApplicationIdentifier` via the **core** Expo plugin (missing AdMob App ID is a separate start crash).
115
+ 2. `NSUserTrackingUsageDescription` when using ATT (`userTrackingUsageDescription` on the core plugin).
116
+ 3. Use this package’s pin (`6.22.0.0`) instead of an older `expo-build-properties` Facebook mediation pod.
117
+ 4. Retest on a shipping iOS release (not a beta), then escalate to Meta / Google’s Meta adapter with the crash report if it still aborts.
65
118
 
66
119
  ## Out of scope
67
120
 
68
121
  - AppLovin MAX host SDK
69
122
  - CloudX / other non-GAM hosts
70
123
  - Fyber/DT Exchange (no Google GAM adapter — do not invent)
124
+ - Invented Expo keys such as `metaAudienceNetworkEnabled` (enablement is “adapter installed + AdMob UI”)
@@ -60,8 +60,11 @@ repositories {
60
60
  }
61
61
 
62
62
  dependencies {
63
+ // React Native bridge for Meta privacy hooks (AdSettings / advertiser-tracking JS API).
64
+ api("com.facebook.react:react-android")
65
+
63
66
  // Google-published Meta Audience Network GAM mediation adapter.
64
- // Pin: package.json sdkVersions.android.googleMobileAdsMediation (docs: 6.22.0.0 as of package publish; verify against current docs/Maven).
67
+ // Pin: package.json sdkVersions.android.googleMobileAdsMediation (docs: 6.22.0.1 as of package publish; verify against current docs/Maven).
65
68
  // Core GMA is provided by react-native-google-mobile-ads; do not re-pin it here.
66
69
  // https://developers.google.com/admob/android/mediation/meta
67
70
  api(mediationArtifact) {
@@ -1,6 +1,6 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <!--
3
- GAM adapter packages carry Google mediation artifacts only.
3
+ GAM facebook adapter: mediation artifact + Meta privacy NativeModule.
4
4
  App ID / measurement flags live in core (react-native-google-mobile-ads).
5
5
  -->
6
6
  <manifest xmlns:android="http://schemas.android.com/apk/res/android" />
@@ -0,0 +1,65 @@
1
+ package io.invertase.googlemobileads.adapters.facebook;
2
+
3
+ import androidx.annotation.NonNull;
4
+ import androidx.annotation.Nullable;
5
+ import com.facebook.ads.AdSettings;
6
+ import com.facebook.react.bridge.ReactApplicationContext;
7
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
8
+ import com.facebook.react.bridge.ReactMethod;
9
+ import com.facebook.react.bridge.ReadableArray;
10
+ import com.facebook.react.module.annotations.ReactModule;
11
+
12
+ /**
13
+ * Meta Audience Network privacy hooks for GAM mediation.
14
+ *
15
+ * <p>{@code setAdvertiserTrackingEnabled} is an iOS-only Meta API. Android
16
+ * {@link AdSettings} (audience-network-sdk 6.22.0) exposes {@code setDataProcessingOptions}
17
+ * instead — verified from the local AAR.
18
+ */
19
+ @ReactModule(name = RNGoogleMobileAdsAdapterFacebookModule.NAME)
20
+ public class RNGoogleMobileAdsAdapterFacebookModule extends ReactContextBaseJavaModule {
21
+ public static final String NAME = "RNGoogleMobileAdsAdapterFacebook";
22
+
23
+ public RNGoogleMobileAdsAdapterFacebookModule(ReactApplicationContext reactContext) {
24
+ super(reactContext);
25
+ }
26
+
27
+ @NonNull
28
+ @Override
29
+ public String getName() {
30
+ return NAME;
31
+ }
32
+
33
+ /**
34
+ * No-op on Android: Meta Audience Network Android SDK has no advertiser-tracking setter.
35
+ * Kept so a single JS call site works on both platforms before GMA initialize.
36
+ */
37
+ @ReactMethod
38
+ public void setAdvertiserTrackingEnabled(boolean enabled) {
39
+ // Intentionally empty — see class javadoc.
40
+ }
41
+
42
+ @ReactMethod
43
+ public void setDataProcessingOptions(@Nullable ReadableArray options) {
44
+ AdSettings.setDataProcessingOptions(toStringArray(options));
45
+ }
46
+
47
+ @ReactMethod
48
+ public void setDataProcessingOptionsWithLocation(
49
+ @Nullable ReadableArray options, int country, int state) {
50
+ AdSettings.setDataProcessingOptions(toStringArray(options), country, state);
51
+ }
52
+
53
+ @NonNull
54
+ private static String[] toStringArray(@Nullable ReadableArray options) {
55
+ if (options == null || options.size() == 0) {
56
+ return new String[0];
57
+ }
58
+ String[] result = new String[options.size()];
59
+ for (int i = 0; i < options.size(); i++) {
60
+ String value = options.getString(i);
61
+ result[i] = value != null ? value : "";
62
+ }
63
+ return result;
64
+ }
65
+ }
@@ -0,0 +1,24 @@
1
+ package io.invertase.googlemobileads.adapters.facebook;
2
+
3
+ import androidx.annotation.NonNull;
4
+ import com.facebook.react.ReactPackage;
5
+ import com.facebook.react.bridge.NativeModule;
6
+ import com.facebook.react.bridge.ReactApplicationContext;
7
+ import com.facebook.react.uimanager.ViewManager;
8
+ import java.util.Collections;
9
+ import java.util.List;
10
+
11
+ /** Registers {@link RNGoogleMobileAdsAdapterFacebookModule} for autolinking. */
12
+ public class RNGoogleMobileAdsAdapterFacebookPackage implements ReactPackage {
13
+ @NonNull
14
+ @Override
15
+ public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
16
+ return Collections.singletonList(new RNGoogleMobileAdsAdapterFacebookModule(reactContext));
17
+ }
18
+
19
+ @NonNull
20
+ @Override
21
+ public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
22
+ return Collections.emptyList();
23
+ }
24
+ }
@@ -0,0 +1,4 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ @interface RNGoogleMobileAdsAdapterFacebook : NSObject <RCTBridgeModule>
4
+ @end
@@ -0,0 +1,31 @@
1
+ #import "RNGoogleMobileAdsAdapterFacebook.h"
2
+
3
+ #import <FBAudienceNetwork/FBAdSettings.h>
4
+
5
+ @implementation RNGoogleMobileAdsAdapterFacebook
6
+
7
+ RCT_EXPORT_MODULE();
8
+
9
+ /**
10
+ * Meta requires advertiser tracking to be set before Google Mobile Ads initialize.
11
+ * Calls FBAdSettings.setAdvertiserTrackingEnabled (FBAudienceNetwork via
12
+ * GoogleMobileAdsMediationFacebook).
13
+ */
14
+ RCT_EXPORT_METHOD(setAdvertiserTrackingEnabled : (BOOL)enabled) {
15
+ [FBAdSettings setAdvertiserTrackingEnabled:enabled];
16
+ }
17
+
18
+ RCT_EXPORT_METHOD(setDataProcessingOptions : (NSArray<NSString *> *)options) {
19
+ [FBAdSettings setDataProcessingOptions:options ?: @[]];
20
+ }
21
+
22
+ RCT_EXPORT_METHOD(setDataProcessingOptionsWithLocation
23
+ : (NSArray<NSString *> *)options country
24
+ : (double)country state
25
+ : (double)state) {
26
+ [FBAdSettings setDataProcessingOptions:options ?: @[]
27
+ country:(NSInteger)country
28
+ state:(NSInteger)state];
29
+ }
30
+
31
+ @end
@@ -4,28 +4,84 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.networkSlug = exports.nativeAdapterClassName = void 0;
7
+ exports.setAdvertiserTrackingEnabled = setAdvertiserTrackingEnabled;
8
+ exports.setDataProcessingOptions = setDataProcessingOptions;
9
+ var _reactNative = require("react-native");
7
10
  /**
8
11
  * Meta Audience Network (Facebook) GAM mediation adapter package public surface.
9
12
  *
10
- * Exports adapter class-name constants for GAM UI paste / docs only. Does **not**
11
- * add JS ad APIs — core `initialize()` adapter statuses remain the discovery
12
- * signal (API design §5.3).
13
+ * Exports adapter class-name constants for GAM UI paste / docs, plus Meta SDK
14
+ * privacy hooks that must run before core `mobileAds().initialize()`:
15
+ * - iOS: `FBAdSettings.setAdvertiserTrackingEnabled`
16
+ * - Android: `AdSettings.setDataProcessingOptions` (no advertiser-tracking API on
17
+ * audience-network-sdk 6.22.0 — verified from the local AAR)
13
18
  *
14
19
  * Native mediation is linked via Google's published adapter:
15
20
  * - Android: `com.google.ads.mediation:facebook`
16
21
  * - iOS: `GoogleMobileAdsMediationFacebook`
17
22
  */
18
23
 
19
- /** Network slug for this Character GAM adapter package. */
24
+ /** Network slug for this GAM adapter package. */
20
25
  const networkSlug = exports.networkSlug = 'facebook';
21
26
 
22
27
  /**
23
28
  * Fully-qualified native mediation adapter class names for AdMob / GAM console paste.
24
- * @see https://developers.google.com/admob/android/mediation/meta
25
- * @see https://developers.google.com/admob/ios/mediation/meta
26
29
  */
27
30
  const nativeAdapterClassName = exports.nativeAdapterClassName = {
28
31
  android: 'com.google.ads.mediation.facebook.FacebookMediationAdapter',
29
32
  ios: 'GADMediationAdapterFacebook'
30
33
  };
34
+ const LINKING_ERROR = `RNGoogleMobileAdsAdapterFacebook native module is not linked. ` + `Rebuild the app after installing @react-native-google-mobile-ads/facebook` + (_reactNative.Platform.OS === 'ios' ? ` (pod install).` : `.`);
35
+ const NativeFacebookAdapter = _reactNative.NativeModules.RNGoogleMobileAdsAdapterFacebook ?? new Proxy({}, {
36
+ get() {
37
+ throw new Error(LINKING_ERROR);
38
+ }
39
+ });
40
+
41
+ /**
42
+ * Set Meta Audience Network advertiser tracking (iOS ATT flag) before GMA initialize.
43
+ *
44
+ * On iOS this calls `FBAdSettings.setAdvertiserTrackingEnabled`. On **iOS 17+** with
45
+ * Audience Network **6.15.0+**, Meta’s `FBAdSettings.h` marks that setter deprecated and
46
+ * unused — the SDK reads `ATTrackingManager.trackingAuthorizationStatus` instead. On Android
47
+ * this is a documented no-op — Meta's Android `AdSettings` has no advertiser-tracking setter
48
+ * (audience-network-sdk 6.22.0).
49
+ *
50
+ * Call after resolving App Tracking Transparency (when applicable on older iOS) and **before**
51
+ * `mobileAds().initialize()`. This JS hook cannot prevent Meta `FBAudienceNetwork` process-start
52
+ * aborts that run before the bridge is up.
53
+ */
54
+ function setAdvertiserTrackingEnabled(enabled) {
55
+ if (typeof enabled !== 'boolean') {
56
+ throw new Error("setAdvertiserTrackingEnabled(*) 'enabled' expected a boolean value.");
57
+ }
58
+ NativeFacebookAdapter.setAdvertiserTrackingEnabled(enabled);
59
+ }
60
+
61
+ /**
62
+ * Set Meta Audience Network data-processing options (e.g. Limited Data Use).
63
+ *
64
+ * On Android this calls `AdSettings.setDataProcessingOptions`. On iOS this calls
65
+ * `FBAdSettings.setDataProcessingOptions` when the Audience Network SDK is linked.
66
+ *
67
+ * Prefer calling before `mobileAds().initialize()`.
68
+ */
69
+ function setDataProcessingOptions(options, country, state) {
70
+ if (!Array.isArray(options) || options.some(item => typeof item !== 'string')) {
71
+ throw new Error("setDataProcessingOptions(*) 'options' expected an array of strings.");
72
+ }
73
+ const hasCountry = country !== undefined;
74
+ const hasState = state !== undefined;
75
+ if (hasCountry !== hasState) {
76
+ throw new Error("setDataProcessingOptions(*) 'country' and 'state' must both be provided or both omitted.");
77
+ }
78
+ if (hasCountry && hasState) {
79
+ if (typeof country !== 'number' || typeof state !== 'number') {
80
+ throw new Error("setDataProcessingOptions(*) 'country' and 'state' expected number values.");
81
+ }
82
+ NativeFacebookAdapter.setDataProcessingOptionsWithLocation(options, country, state);
83
+ return;
84
+ }
85
+ NativeFacebookAdapter.setDataProcessingOptions(options);
86
+ }
31
87
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["networkSlug","exports","nativeAdapterClassName","android","ios"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA;AACO,MAAMA,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAG,UAAmB;;AAE9C;AACA;AACA;AACA;AACA;AACO,MAAME,sBAA8C,GAAAD,OAAA,CAAAC,sBAAA,GAAG;EAC5DC,OAAO,EAAE,4DAA4D;EACrEC,GAAG,EAAE;AACP,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","networkSlug","exports","nativeAdapterClassName","android","ios","LINKING_ERROR","Platform","OS","NativeFacebookAdapter","NativeModules","RNGoogleMobileAdsAdapterFacebook","Proxy","get","Error","setAdvertiserTrackingEnabled","enabled","setDataProcessingOptions","options","country","state","Array","isArray","some","item","hasCountry","undefined","hasState","setDataProcessingOptionsWithLocation"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA;AACO,MAAMC,WAAW,GAAAC,OAAA,CAAAD,WAAA,GAAG,UAAmB;;AAE9C;AACA;AACA;AACO,MAAME,sBAA8C,GAAAD,OAAA,CAAAC,sBAAA,GAAG;EAC5DC,OAAO,EAAE,4DAA4D;EACrEC,GAAG,EAAE;AACP,CAAC;AAQD,MAAMC,aAAa,GACjB,gEAAgE,GAChE,2EAA2E,IAC1EC,qBAAQ,CAACC,EAAE,KAAK,KAAK,GAAG,iBAAiB,GAAG,GAAG,CAAC;AAEnD,MAAMC,qBAAkD,GACrDC,0BAAa,CAACC,gCAAgC,IAC/C,IAAIC,KAAK,CAAC,CAAC,CAAC,EAAiC;EAC3CC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACR,aAAa,CAAC;EAChC;AACF,CAAC,CAAC;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASS,4BAA4BA,CAACC,OAAgB,EAAQ;EACnE,IAAI,OAAOA,OAAO,KAAK,SAAS,EAAE;IAChC,MAAM,IAAIF,KAAK,CACb,qEACF,CAAC;EACH;EACAL,qBAAqB,CAACM,4BAA4B,CAACC,OAAO,CAAC;AAC7D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,wBAAwBA,CACtCC,OAAiB,EACjBC,OAAgB,EAChBC,KAAc,EACR;EACN,IAAI,CAACC,KAAK,CAACC,OAAO,CAACJ,OAAO,CAAC,IAAIA,OAAO,CAACK,IAAI,CAACC,IAAI,IAAI,OAAOA,IAAI,KAAK,QAAQ,CAAC,EAAE;IAC7E,MAAM,IAAIV,KAAK,CACb,qEACF,CAAC;EACH;EAEA,MAAMW,UAAU,GAAGN,OAAO,KAAKO,SAAS;EACxC,MAAMC,QAAQ,GAAGP,KAAK,KAAKM,SAAS;EACpC,IAAID,UAAU,KAAKE,QAAQ,EAAE;IAC3B,MAAM,IAAIb,KAAK,CACb,0FACF,CAAC;EACH;EAEA,IAAIW,UAAU,IAAIE,QAAQ,EAAE;IAC1B,IAAI,OAAOR,OAAO,KAAK,QAAQ,IAAI,OAAOC,KAAK,KAAK,QAAQ,EAAE;MAC5D,MAAM,IAAIN,KAAK,CACb,2EACF,CAAC;IACH;IACAL,qBAAqB,CAACmB,oCAAoC,CAACV,OAAO,EAAEC,OAAO,EAAEC,KAAK,CAAC;IACnF;EACF;EAEAX,qBAAqB,CAACQ,wBAAwB,CAACC,OAAO,CAAC;AACzD","ignoreList":[]}
@@ -1,27 +1,82 @@
1
1
  "use strict";
2
2
 
3
+ import { NativeModules, Platform } from 'react-native';
4
+
3
5
  /**
4
6
  * Meta Audience Network (Facebook) GAM mediation adapter package public surface.
5
7
  *
6
- * Exports adapter class-name constants for GAM UI paste / docs only. Does **not**
7
- * add JS ad APIs — core `initialize()` adapter statuses remain the discovery
8
- * signal (API design §5.3).
8
+ * Exports adapter class-name constants for GAM UI paste / docs, plus Meta SDK
9
+ * privacy hooks that must run before core `mobileAds().initialize()`:
10
+ * - iOS: `FBAdSettings.setAdvertiserTrackingEnabled`
11
+ * - Android: `AdSettings.setDataProcessingOptions` (no advertiser-tracking API on
12
+ * audience-network-sdk 6.22.0 — verified from the local AAR)
9
13
  *
10
14
  * Native mediation is linked via Google's published adapter:
11
15
  * - Android: `com.google.ads.mediation:facebook`
12
16
  * - iOS: `GoogleMobileAdsMediationFacebook`
13
17
  */
14
18
 
15
- /** Network slug for this Character GAM adapter package. */
19
+ /** Network slug for this GAM adapter package. */
16
20
  export const networkSlug = 'facebook';
17
21
 
18
22
  /**
19
23
  * Fully-qualified native mediation adapter class names for AdMob / GAM console paste.
20
- * @see https://developers.google.com/admob/android/mediation/meta
21
- * @see https://developers.google.com/admob/ios/mediation/meta
22
24
  */
23
25
  export const nativeAdapterClassName = {
24
26
  android: 'com.google.ads.mediation.facebook.FacebookMediationAdapter',
25
27
  ios: 'GADMediationAdapterFacebook'
26
28
  };
29
+ const LINKING_ERROR = `RNGoogleMobileAdsAdapterFacebook native module is not linked. ` + `Rebuild the app after installing @react-native-google-mobile-ads/facebook` + (Platform.OS === 'ios' ? ` (pod install).` : `.`);
30
+ const NativeFacebookAdapter = NativeModules.RNGoogleMobileAdsAdapterFacebook ?? new Proxy({}, {
31
+ get() {
32
+ throw new Error(LINKING_ERROR);
33
+ }
34
+ });
35
+
36
+ /**
37
+ * Set Meta Audience Network advertiser tracking (iOS ATT flag) before GMA initialize.
38
+ *
39
+ * On iOS this calls `FBAdSettings.setAdvertiserTrackingEnabled`. On **iOS 17+** with
40
+ * Audience Network **6.15.0+**, Meta’s `FBAdSettings.h` marks that setter deprecated and
41
+ * unused — the SDK reads `ATTrackingManager.trackingAuthorizationStatus` instead. On Android
42
+ * this is a documented no-op — Meta's Android `AdSettings` has no advertiser-tracking setter
43
+ * (audience-network-sdk 6.22.0).
44
+ *
45
+ * Call after resolving App Tracking Transparency (when applicable on older iOS) and **before**
46
+ * `mobileAds().initialize()`. This JS hook cannot prevent Meta `FBAudienceNetwork` process-start
47
+ * aborts that run before the bridge is up.
48
+ */
49
+ export function setAdvertiserTrackingEnabled(enabled) {
50
+ if (typeof enabled !== 'boolean') {
51
+ throw new Error("setAdvertiserTrackingEnabled(*) 'enabled' expected a boolean value.");
52
+ }
53
+ NativeFacebookAdapter.setAdvertiserTrackingEnabled(enabled);
54
+ }
55
+
56
+ /**
57
+ * Set Meta Audience Network data-processing options (e.g. Limited Data Use).
58
+ *
59
+ * On Android this calls `AdSettings.setDataProcessingOptions`. On iOS this calls
60
+ * `FBAdSettings.setDataProcessingOptions` when the Audience Network SDK is linked.
61
+ *
62
+ * Prefer calling before `mobileAds().initialize()`.
63
+ */
64
+ export function setDataProcessingOptions(options, country, state) {
65
+ if (!Array.isArray(options) || options.some(item => typeof item !== 'string')) {
66
+ throw new Error("setDataProcessingOptions(*) 'options' expected an array of strings.");
67
+ }
68
+ const hasCountry = country !== undefined;
69
+ const hasState = state !== undefined;
70
+ if (hasCountry !== hasState) {
71
+ throw new Error("setDataProcessingOptions(*) 'country' and 'state' must both be provided or both omitted.");
72
+ }
73
+ if (hasCountry && hasState) {
74
+ if (typeof country !== 'number' || typeof state !== 'number') {
75
+ throw new Error("setDataProcessingOptions(*) 'country' and 'state' expected number values.");
76
+ }
77
+ NativeFacebookAdapter.setDataProcessingOptionsWithLocation(options, country, state);
78
+ return;
79
+ }
80
+ NativeFacebookAdapter.setDataProcessingOptions(options);
81
+ }
27
82
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["networkSlug","nativeAdapterClassName","android","ios"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA;AACA,OAAO,MAAMA,WAAW,GAAG,UAAmB;;AAE9C;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMC,sBAA8C,GAAG;EAC5DC,OAAO,EAAE,4DAA4D;EACrEC,GAAG,EAAE;AACP,CAAC","ignoreList":[]}
1
+ {"version":3,"names":["NativeModules","Platform","networkSlug","nativeAdapterClassName","android","ios","LINKING_ERROR","OS","NativeFacebookAdapter","RNGoogleMobileAdsAdapterFacebook","Proxy","get","Error","setAdvertiserTrackingEnabled","enabled","setDataProcessingOptions","options","country","state","Array","isArray","some","item","hasCountry","undefined","hasState","setDataProcessingOptionsWithLocation"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;;AAEtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA;AACA,OAAO,MAAMC,WAAW,GAAG,UAAmB;;AAE9C;AACA;AACA;AACA,OAAO,MAAMC,sBAA8C,GAAG;EAC5DC,OAAO,EAAE,4DAA4D;EACrEC,GAAG,EAAE;AACP,CAAC;AAQD,MAAMC,aAAa,GACjB,gEAAgE,GAChE,2EAA2E,IAC1EL,QAAQ,CAACM,EAAE,KAAK,KAAK,GAAG,iBAAiB,GAAG,GAAG,CAAC;AAEnD,MAAMC,qBAAkD,GACrDR,aAAa,CAACS,gCAAgC,IAC/C,IAAIC,KAAK,CAAC,CAAC,CAAC,EAAiC;EAC3CC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACN,aAAa,CAAC;EAChC;AACF,CAAC,CAAC;;AAEJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASO,4BAA4BA,CAACC,OAAgB,EAAQ;EACnE,IAAI,OAAOA,OAAO,KAAK,SAAS,EAAE;IAChC,MAAM,IAAIF,KAAK,CACb,qEACF,CAAC;EACH;EACAJ,qBAAqB,CAACK,4BAA4B,CAACC,OAAO,CAAC;AAC7D;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,wBAAwBA,CACtCC,OAAiB,EACjBC,OAAgB,EAChBC,KAAc,EACR;EACN,IAAI,CAACC,KAAK,CAACC,OAAO,CAACJ,OAAO,CAAC,IAAIA,OAAO,CAACK,IAAI,CAACC,IAAI,IAAI,OAAOA,IAAI,KAAK,QAAQ,CAAC,EAAE;IAC7E,MAAM,IAAIV,KAAK,CACb,qEACF,CAAC;EACH;EAEA,MAAMW,UAAU,GAAGN,OAAO,KAAKO,SAAS;EACxC,MAAMC,QAAQ,GAAGP,KAAK,KAAKM,SAAS;EACpC,IAAID,UAAU,KAAKE,QAAQ,EAAE;IAC3B,MAAM,IAAIb,KAAK,CACb,0FACF,CAAC;EACH;EAEA,IAAIW,UAAU,IAAIE,QAAQ,EAAE;IAC1B,IAAI,OAAOR,OAAO,KAAK,QAAQ,IAAI,OAAOC,KAAK,KAAK,QAAQ,EAAE;MAC5D,MAAM,IAAIN,KAAK,CACb,2EACF,CAAC;IACH;IACAJ,qBAAqB,CAACkB,oCAAoC,CAACV,OAAO,EAAEC,OAAO,EAAEC,KAAK,CAAC;IACnF;EACF;EAEAV,qBAAqB,CAACO,wBAAwB,CAACC,OAAO,CAAC;AACzD","ignoreList":[]}
@@ -1,9 +1,11 @@
1
1
  /**
2
2
  * Meta Audience Network (Facebook) GAM mediation adapter package public surface.
3
3
  *
4
- * Exports adapter class-name constants for GAM UI paste / docs only. Does **not**
5
- * add JS ad APIs — core `initialize()` adapter statuses remain the discovery
6
- * signal (API design §5.3).
4
+ * Exports adapter class-name constants for GAM UI paste / docs, plus Meta SDK
5
+ * privacy hooks that must run before core `mobileAds().initialize()`:
6
+ * - iOS: `FBAdSettings.setAdvertiserTrackingEnabled`
7
+ * - Android: `AdSettings.setDataProcessingOptions` (no advertiser-tracking API on
8
+ * audience-network-sdk 6.22.0 — verified from the local AAR)
7
9
  *
8
10
  * Native mediation is linked via Google's published adapter:
9
11
  * - Android: `com.google.ads.mediation:facebook`
@@ -13,12 +15,33 @@ export type NativeAdapterClassName = {
13
15
  android: string;
14
16
  ios: string;
15
17
  };
16
- /** Network slug for this Character GAM adapter package. */
18
+ /** Network slug for this GAM adapter package. */
17
19
  export declare const networkSlug: "facebook";
18
20
  /**
19
21
  * Fully-qualified native mediation adapter class names for AdMob / GAM console paste.
20
- * @see https://developers.google.com/admob/android/mediation/meta
21
- * @see https://developers.google.com/admob/ios/mediation/meta
22
22
  */
23
23
  export declare const nativeAdapterClassName: NativeAdapterClassName;
24
+ /**
25
+ * Set Meta Audience Network advertiser tracking (iOS ATT flag) before GMA initialize.
26
+ *
27
+ * On iOS this calls `FBAdSettings.setAdvertiserTrackingEnabled`. On **iOS 17+** with
28
+ * Audience Network **6.15.0+**, Meta’s `FBAdSettings.h` marks that setter deprecated and
29
+ * unused — the SDK reads `ATTrackingManager.trackingAuthorizationStatus` instead. On Android
30
+ * this is a documented no-op — Meta's Android `AdSettings` has no advertiser-tracking setter
31
+ * (audience-network-sdk 6.22.0).
32
+ *
33
+ * Call after resolving App Tracking Transparency (when applicable on older iOS) and **before**
34
+ * `mobileAds().initialize()`. This JS hook cannot prevent Meta `FBAudienceNetwork` process-start
35
+ * aborts that run before the bridge is up.
36
+ */
37
+ export declare function setAdvertiserTrackingEnabled(enabled: boolean): void;
38
+ /**
39
+ * Set Meta Audience Network data-processing options (e.g. Limited Data Use).
40
+ *
41
+ * On Android this calls `AdSettings.setDataProcessingOptions`. On iOS this calls
42
+ * `FBAdSettings.setDataProcessingOptions` when the Audience Network SDK is linked.
43
+ *
44
+ * Prefer calling before `mobileAds().initialize()`.
45
+ */
46
+ export declare function setDataProcessingOptions(options: string[], country?: number, state?: number): void;
24
47
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,2DAA2D;AAC3D,eAAO,MAAM,WAAW,EAAG,UAAmB,CAAC;AAE/C;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,sBAGpC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,WAAW,EAAG,UAAmB,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,sBAGpC,CAAC;AAqBF;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAOnE;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CA0BN"}
@@ -1,9 +1,11 @@
1
1
  /**
2
2
  * Meta Audience Network (Facebook) GAM mediation adapter package public surface.
3
3
  *
4
- * Exports adapter class-name constants for GAM UI paste / docs only. Does **not**
5
- * add JS ad APIs — core `initialize()` adapter statuses remain the discovery
6
- * signal (API design §5.3).
4
+ * Exports adapter class-name constants for GAM UI paste / docs, plus Meta SDK
5
+ * privacy hooks that must run before core `mobileAds().initialize()`:
6
+ * - iOS: `FBAdSettings.setAdvertiserTrackingEnabled`
7
+ * - Android: `AdSettings.setDataProcessingOptions` (no advertiser-tracking API on
8
+ * audience-network-sdk 6.22.0 — verified from the local AAR)
7
9
  *
8
10
  * Native mediation is linked via Google's published adapter:
9
11
  * - Android: `com.google.ads.mediation:facebook`
@@ -13,12 +15,33 @@ export type NativeAdapterClassName = {
13
15
  android: string;
14
16
  ios: string;
15
17
  };
16
- /** Network slug for this Character GAM adapter package. */
18
+ /** Network slug for this GAM adapter package. */
17
19
  export declare const networkSlug: "facebook";
18
20
  /**
19
21
  * Fully-qualified native mediation adapter class names for AdMob / GAM console paste.
20
- * @see https://developers.google.com/admob/android/mediation/meta
21
- * @see https://developers.google.com/admob/ios/mediation/meta
22
22
  */
23
23
  export declare const nativeAdapterClassName: NativeAdapterClassName;
24
+ /**
25
+ * Set Meta Audience Network advertiser tracking (iOS ATT flag) before GMA initialize.
26
+ *
27
+ * On iOS this calls `FBAdSettings.setAdvertiserTrackingEnabled`. On **iOS 17+** with
28
+ * Audience Network **6.15.0+**, Meta’s `FBAdSettings.h` marks that setter deprecated and
29
+ * unused — the SDK reads `ATTrackingManager.trackingAuthorizationStatus` instead. On Android
30
+ * this is a documented no-op — Meta's Android `AdSettings` has no advertiser-tracking setter
31
+ * (audience-network-sdk 6.22.0).
32
+ *
33
+ * Call after resolving App Tracking Transparency (when applicable on older iOS) and **before**
34
+ * `mobileAds().initialize()`. This JS hook cannot prevent Meta `FBAudienceNetwork` process-start
35
+ * aborts that run before the bridge is up.
36
+ */
37
+ export declare function setAdvertiserTrackingEnabled(enabled: boolean): void;
38
+ /**
39
+ * Set Meta Audience Network data-processing options (e.g. Limited Data Use).
40
+ *
41
+ * On Android this calls `AdSettings.setDataProcessingOptions`. On iOS this calls
42
+ * `FBAdSettings.setDataProcessingOptions` when the Audience Network SDK is linked.
43
+ *
44
+ * Prefer calling before `mobileAds().initialize()`.
45
+ */
46
+ export declare function setDataProcessingOptions(options: string[], country?: number, state?: number): void;
24
47
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,2DAA2D;AAC3D,eAAO,MAAM,WAAW,EAAG,UAAmB,CAAC;AAE/C;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,sBAGpC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,sBAAsB,GAAG;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,WAAW,EAAG,UAAmB,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,sBAGpC,CAAC;AAqBF;;;;;;;;;;;;GAYG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAOnE;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,MAAM,GACb,IAAI,CA0BN"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@react-native-google-mobile-ads/facebook",
3
- "version": "17.2.0",
4
- "description": "Meta Audience Network (Facebook) Google Mobile Ads (GAM) mediation adapter for react-native-google-mobile-ads. Links the official Google mediation adapter on Android and iOS; does not add JS ad APIs.",
3
+ "version": "17.3.0",
4
+ "description": "Meta Audience Network (Facebook) Google Mobile Ads (GAM) mediation adapter for react-native-google-mobile-ads. Links the official Google mediation adapter on Android and iOS, and exposes Meta privacy hooks (advertiser tracking / data-processing options) for use before GMA initialize.",
5
5
  "author": "Invertase <oss@invertase.io> (http://invertase.io)",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -77,7 +77,7 @@
77
77
  "targetSdk": 36,
78
78
  "compileSdk": 36,
79
79
  "buildTools": "36.0.0",
80
- "googleMobileAdsMediation": "6.22.0.0"
80
+ "googleMobileAdsMediation": "6.22.0.1"
81
81
  }
82
82
  },
83
83
  "react-native-builder-bob": {
@@ -123,9 +123,9 @@
123
123
  "devDependencies": {
124
124
  "@expo/config-plugins": "^54.0.4",
125
125
  "react-native-builder-bob": "^0.40.13",
126
- "react-native-google-mobile-ads": "17.2.0",
126
+ "react-native-google-mobile-ads": "17.3.0",
127
127
  "rimraf": "^6.0.1",
128
128
  "typescript": "^5.9.3"
129
129
  },
130
- "gitHead": "054a88b0d42727b32e74b09191f51c469c53f417"
130
+ "gitHead": "84973e83de32daede263f2add5fbf07df5b22df4"
131
131
  }
@@ -0,0 +1,45 @@
1
+ import {
2
+ KNOWN_PLUGIN_PARAMETER_KEYS,
3
+ warnUnknownPluginParameters,
4
+ } from '../src';
5
+
6
+ describe('facebook Expo plugin unknown parameters', () => {
7
+ let warnSpy: jest.SpyInstance;
8
+
9
+ beforeEach(() => {
10
+ warnSpy = jest.spyOn(console, 'warn').mockImplementation(() => undefined);
11
+ });
12
+
13
+ afterEach(() => {
14
+ warnSpy.mockRestore();
15
+ });
16
+
17
+ it('exports skAdNetworkItems as the only known key', () => {
18
+ expect(KNOWN_PLUGIN_PARAMETER_KEYS).toEqual(['skAdNetworkItems']);
19
+ });
20
+
21
+ it('does not warn for skAdNetworkItems', () => {
22
+ warnUnknownPluginParameters({ skAdNetworkItems: ['abc.skadnetwork'] });
23
+ expect(warnSpy).not.toHaveBeenCalled();
24
+ });
25
+
26
+ it('warns that Meta advertiser-tracking keys are runtime JS APIs', () => {
27
+ warnUnknownPluginParameters({
28
+ metaAdvertiserTrackingEnabled: true,
29
+ advertiserTrackingEnabled: false,
30
+ });
31
+
32
+ expect(warnSpy).toHaveBeenCalled();
33
+ const message = warnSpy.mock.calls.map(call => call[0]).join('\n');
34
+ expect(message).toMatch(/metaAdvertiserTrackingEnabled|advertiserTrackingEnabled/);
35
+ expect(message).toMatch(/setAdvertiserTrackingEnabled/);
36
+ expect(message).toMatch(/before mobileAds\(\)\.initialize/);
37
+ });
38
+
39
+ it('warns for other unknown keys', () => {
40
+ warnUnknownPluginParameters({ fooBar: 1 });
41
+ expect(warnSpy).toHaveBeenCalledTimes(1);
42
+ expect(warnSpy.mock.calls[0][0]).toMatch(/fooBar/);
43
+ expect(warnSpy.mock.calls[0][0]).toMatch(/skAdNetworkItems/);
44
+ });
45
+ });
@@ -7,9 +7,17 @@ type PluginParameters = {
7
7
  */
8
8
  skAdNetworkItems?: string[];
9
9
  };
10
+ /** Keys accepted by the facebook adapter Expo config plugin. */
11
+ export declare const KNOWN_PLUGIN_PARAMETER_KEYS: readonly ["skAdNetworkItems"];
12
+ /**
13
+ * Warn when Expo plugin options include keys this adapter plugin does not apply.
14
+ * Exported for unit tests.
15
+ */
16
+ export declare function warnUnknownPluginParameters(params: Record<string, unknown> | undefined): void;
10
17
  /**
11
18
  * Optional Expo config plugin for `@react-native-google-mobile-ads/facebook`.
12
- * Does not set GMA app IDs (core plugin).
19
+ * Does not set GMA app IDs (core plugin). Does not set advertiser tracking
20
+ * (runtime JS — ATT status is not knowable at prebuild time).
13
21
  */
14
22
  declare const withRNGoogleMobileAdsAdapterFacebook: ConfigPlugin<PluginParameters>;
15
23
  export default withRNGoogleMobileAdsAdapterFacebook;
@@ -1,6 +1,35 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KNOWN_PLUGIN_PARAMETER_KEYS = void 0;
4
+ exports.warnUnknownPluginParameters = warnUnknownPluginParameters;
3
5
  const config_plugins_1 = require("@expo/config-plugins");
6
+ /** Keys accepted by the facebook adapter Expo config plugin. */
7
+ exports.KNOWN_PLUGIN_PARAMETER_KEYS = ['skAdNetworkItems'];
8
+ const RUNTIME_META_KEYS_HINT = 'Advertiser tracking and data-processing options are runtime JS APIs on ' +
9
+ '@react-native-google-mobile-ads/facebook (setAdvertiserTrackingEnabled / setDataProcessingOptions), ' +
10
+ 'not Expo plugin config. Call them before mobileAds().initialize().';
11
+ /**
12
+ * Warn when Expo plugin options include keys this adapter plugin does not apply.
13
+ * Exported for unit tests.
14
+ */
15
+ function warnUnknownPluginParameters(params) {
16
+ if (params == null || typeof params !== 'object' || Array.isArray(params)) {
17
+ return;
18
+ }
19
+ const known = new Set(exports.KNOWN_PLUGIN_PARAMETER_KEYS);
20
+ const unknownKeys = Object.keys(params).filter(key => !known.has(key));
21
+ if (unknownKeys.length === 0) {
22
+ return;
23
+ }
24
+ const runtimeKeys = unknownKeys.filter(key => /^(meta)?(AdvertiserTrackingEnabled|DataProcessingOptions|AudienceNetworkEnabled)$/i.test(key));
25
+ const otherKeys = unknownKeys.filter(key => !runtimeKeys.includes(key));
26
+ if (runtimeKeys.length > 0) {
27
+ console.warn(`[@react-native-google-mobile-ads/facebook] Ignoring Expo plugin option(s): ${runtimeKeys.join(', ')}. ${RUNTIME_META_KEYS_HINT}`);
28
+ }
29
+ if (otherKeys.length > 0) {
30
+ console.warn(`[@react-native-google-mobile-ads/facebook] Ignoring unknown Expo plugin option(s): ${otherKeys.join(', ')}. Known keys: ${exports.KNOWN_PLUGIN_PARAMETER_KEYS.join(', ')}.`);
31
+ }
32
+ }
4
33
  const withAdapterSkAdNetworkItems = (config, skAdNetworkItems) => {
5
34
  if (skAdNetworkItems === undefined || skAdNetworkItems.length === 0) {
6
35
  return config;
@@ -17,9 +46,12 @@ const withAdapterSkAdNetworkItems = (config, skAdNetworkItems) => {
17
46
  };
18
47
  /**
19
48
  * Optional Expo config plugin for `@react-native-google-mobile-ads/facebook`.
20
- * Does not set GMA app IDs (core plugin).
49
+ * Does not set GMA app IDs (core plugin). Does not set advertiser tracking
50
+ * (runtime JS — ATT status is not knowable at prebuild time).
21
51
  */
22
- const withRNGoogleMobileAdsAdapterFacebook = (config, { skAdNetworkItems } = {}) => {
52
+ const withRNGoogleMobileAdsAdapterFacebook = (config, props = {}) => {
53
+ warnUnknownPluginParameters(props);
54
+ const { skAdNetworkItems } = props;
23
55
  return (0, config_plugins_1.withPlugins)(config, [[withAdapterSkAdNetworkItems, skAdNetworkItems]]);
24
56
  };
25
57
  exports.default = withRNGoogleMobileAdsAdapterFacebook;
@@ -9,6 +9,55 @@ type PluginParameters = {
9
9
  skAdNetworkItems?: string[];
10
10
  };
11
11
 
12
+ /** Keys accepted by the facebook adapter Expo config plugin. */
13
+ export const KNOWN_PLUGIN_PARAMETER_KEYS = ['skAdNetworkItems'] as const;
14
+
15
+ const RUNTIME_META_KEYS_HINT =
16
+ 'Advertiser tracking and data-processing options are runtime JS APIs on ' +
17
+ '@react-native-google-mobile-ads/facebook (setAdvertiserTrackingEnabled / setDataProcessingOptions), ' +
18
+ 'not Expo plugin config. Call them before mobileAds().initialize().';
19
+
20
+ /**
21
+ * Warn when Expo plugin options include keys this adapter plugin does not apply.
22
+ * Exported for unit tests.
23
+ */
24
+ export function warnUnknownPluginParameters(
25
+ params: Record<string, unknown> | undefined,
26
+ ): void {
27
+ if (params == null || typeof params !== 'object' || Array.isArray(params)) {
28
+ return;
29
+ }
30
+
31
+ const known = new Set<string>(KNOWN_PLUGIN_PARAMETER_KEYS);
32
+ const unknownKeys = Object.keys(params).filter(key => !known.has(key));
33
+ if (unknownKeys.length === 0) {
34
+ return;
35
+ }
36
+
37
+ const runtimeKeys = unknownKeys.filter(key =>
38
+ /^(meta)?(AdvertiserTrackingEnabled|DataProcessingOptions|AudienceNetworkEnabled)$/i.test(
39
+ key,
40
+ ),
41
+ );
42
+ const otherKeys = unknownKeys.filter(key => !runtimeKeys.includes(key));
43
+
44
+ if (runtimeKeys.length > 0) {
45
+ console.warn(
46
+ `[@react-native-google-mobile-ads/facebook] Ignoring Expo plugin option(s): ${runtimeKeys.join(
47
+ ', ',
48
+ )}. ${RUNTIME_META_KEYS_HINT}`,
49
+ );
50
+ }
51
+
52
+ if (otherKeys.length > 0) {
53
+ console.warn(
54
+ `[@react-native-google-mobile-ads/facebook] Ignoring unknown Expo plugin option(s): ${otherKeys.join(
55
+ ', ',
56
+ )}. Known keys: ${KNOWN_PLUGIN_PARAMETER_KEYS.join(', ')}.`,
57
+ );
58
+ }
59
+ }
60
+
12
61
  const withAdapterSkAdNetworkItems: ConfigPlugin<PluginParameters['skAdNetworkItems']> = (
13
62
  config,
14
63
  skAdNetworkItems,
@@ -40,12 +89,16 @@ const withAdapterSkAdNetworkItems: ConfigPlugin<PluginParameters['skAdNetworkIte
40
89
 
41
90
  /**
42
91
  * Optional Expo config plugin for `@react-native-google-mobile-ads/facebook`.
43
- * Does not set GMA app IDs (core plugin).
92
+ * Does not set GMA app IDs (core plugin). Does not set advertiser tracking
93
+ * (runtime JS — ATT status is not knowable at prebuild time).
44
94
  */
45
95
  const withRNGoogleMobileAdsAdapterFacebook: ConfigPlugin<PluginParameters> = (
46
96
  config,
47
- { skAdNetworkItems } = {},
97
+ props = {},
48
98
  ) => {
99
+ warnUnknownPluginParameters(props as Record<string, unknown>);
100
+
101
+ const { skAdNetworkItems } = props;
49
102
  return withPlugins(config, [[withAdapterSkAdNetworkItems, skAdNetworkItems]]);
50
103
  };
51
104
 
@@ -1,11 +1,15 @@
1
1
  /**
2
- * Autolinking entry for the GAM adapter package.
3
- * Adapters ship native mediation artifacts only — no TurboModule / Fabric view.
2
+ * Autolinking entry for the GAM facebook adapter package.
3
+ * Registers the Meta privacy NativeModule (advertiser tracking / data-processing options).
4
4
  */
5
5
  module.exports = {
6
6
  dependency: {
7
7
  platforms: {
8
- android: {},
8
+ android: {
9
+ packageImportPath:
10
+ 'import io.invertase.googlemobileads.adapters.facebook.RNGoogleMobileAdsAdapterFacebookPackage;',
11
+ packageInstance: 'new RNGoogleMobileAdsAdapterFacebookPackage()',
12
+ },
9
13
  ios: {},
10
14
  },
11
15
  },
package/src/index.ts CHANGED
@@ -1,9 +1,13 @@
1
+ import { NativeModules, Platform } from 'react-native';
2
+
1
3
  /**
2
4
  * Meta Audience Network (Facebook) GAM mediation adapter package public surface.
3
5
  *
4
- * Exports adapter class-name constants for GAM UI paste / docs only. Does **not**
5
- * add JS ad APIs — core `initialize()` adapter statuses remain the discovery
6
- * signal (API design §5.3).
6
+ * Exports adapter class-name constants for GAM UI paste / docs, plus Meta SDK
7
+ * privacy hooks that must run before core `mobileAds().initialize()`:
8
+ * - iOS: `FBAdSettings.setAdvertiserTrackingEnabled`
9
+ * - Android: `AdSettings.setDataProcessingOptions` (no advertiser-tracking API on
10
+ * audience-network-sdk 6.22.0 — verified from the local AAR)
7
11
  *
8
12
  * Native mediation is linked via Google's published adapter:
9
13
  * - Android: `com.google.ads.mediation:facebook`
@@ -15,15 +19,94 @@ export type NativeAdapterClassName = {
15
19
  ios: string;
16
20
  };
17
21
 
18
- /** Network slug for this Character GAM adapter package. */
22
+ /** Network slug for this GAM adapter package. */
19
23
  export const networkSlug = 'facebook' as const;
20
24
 
21
25
  /**
22
26
  * Fully-qualified native mediation adapter class names for AdMob / GAM console paste.
23
- * @see https://developers.google.com/admob/android/mediation/meta
24
- * @see https://developers.google.com/admob/ios/mediation/meta
25
27
  */
26
28
  export const nativeAdapterClassName: NativeAdapterClassName = {
27
29
  android: 'com.google.ads.mediation.facebook.FacebookMediationAdapter',
28
30
  ios: 'GADMediationAdapterFacebook',
29
31
  };
32
+
33
+ type NativeFacebookAdapterModule = {
34
+ setAdvertiserTrackingEnabled(enabled: boolean): void;
35
+ setDataProcessingOptions(options: string[]): void;
36
+ setDataProcessingOptionsWithLocation(options: string[], country: number, state: number): void;
37
+ };
38
+
39
+ const LINKING_ERROR =
40
+ `RNGoogleMobileAdsAdapterFacebook native module is not linked. ` +
41
+ `Rebuild the app after installing @react-native-google-mobile-ads/facebook` +
42
+ (Platform.OS === 'ios' ? ` (pod install).` : `.`);
43
+
44
+ const NativeFacebookAdapter: NativeFacebookAdapterModule =
45
+ (NativeModules.RNGoogleMobileAdsAdapterFacebook as NativeFacebookAdapterModule | undefined) ??
46
+ new Proxy({} as NativeFacebookAdapterModule, {
47
+ get() {
48
+ throw new Error(LINKING_ERROR);
49
+ },
50
+ });
51
+
52
+ /**
53
+ * Set Meta Audience Network advertiser tracking (iOS ATT flag) before GMA initialize.
54
+ *
55
+ * On iOS this calls `FBAdSettings.setAdvertiserTrackingEnabled`. On **iOS 17+** with
56
+ * Audience Network **6.15.0+**, Meta’s `FBAdSettings.h` marks that setter deprecated and
57
+ * unused — the SDK reads `ATTrackingManager.trackingAuthorizationStatus` instead. On Android
58
+ * this is a documented no-op — Meta's Android `AdSettings` has no advertiser-tracking setter
59
+ * (audience-network-sdk 6.22.0).
60
+ *
61
+ * Call after resolving App Tracking Transparency (when applicable on older iOS) and **before**
62
+ * `mobileAds().initialize()`. This JS hook cannot prevent Meta `FBAudienceNetwork` process-start
63
+ * aborts that run before the bridge is up.
64
+ */
65
+ export function setAdvertiserTrackingEnabled(enabled: boolean): void {
66
+ if (typeof enabled !== 'boolean') {
67
+ throw new Error(
68
+ "setAdvertiserTrackingEnabled(*) 'enabled' expected a boolean value.",
69
+ );
70
+ }
71
+ NativeFacebookAdapter.setAdvertiserTrackingEnabled(enabled);
72
+ }
73
+
74
+ /**
75
+ * Set Meta Audience Network data-processing options (e.g. Limited Data Use).
76
+ *
77
+ * On Android this calls `AdSettings.setDataProcessingOptions`. On iOS this calls
78
+ * `FBAdSettings.setDataProcessingOptions` when the Audience Network SDK is linked.
79
+ *
80
+ * Prefer calling before `mobileAds().initialize()`.
81
+ */
82
+ export function setDataProcessingOptions(
83
+ options: string[],
84
+ country?: number,
85
+ state?: number,
86
+ ): void {
87
+ if (!Array.isArray(options) || options.some(item => typeof item !== 'string')) {
88
+ throw new Error(
89
+ "setDataProcessingOptions(*) 'options' expected an array of strings.",
90
+ );
91
+ }
92
+
93
+ const hasCountry = country !== undefined;
94
+ const hasState = state !== undefined;
95
+ if (hasCountry !== hasState) {
96
+ throw new Error(
97
+ "setDataProcessingOptions(*) 'country' and 'state' must both be provided or both omitted.",
98
+ );
99
+ }
100
+
101
+ if (hasCountry && hasState) {
102
+ if (typeof country !== 'number' || typeof state !== 'number') {
103
+ throw new Error(
104
+ "setDataProcessingOptions(*) 'country' and 'state' expected number values.",
105
+ );
106
+ }
107
+ NativeFacebookAdapter.setDataProcessingOptionsWithLocation(options, country, state);
108
+ return;
109
+ }
110
+
111
+ NativeFacebookAdapter.setDataProcessingOptions(options);
112
+ }
@@ -1,10 +0,0 @@
1
- package io.invertase.googlemobileads.adapters.facebook;
2
-
3
- /**
4
- * Package marker so the Android library module has a compilable source root.
5
- * This package does not expose a TurboModule — mediation is linked via Gradle
6
- * ({@code com.google.ads.mediation:facebook}).
7
- */
8
- public final class AdapterPackageMarker {
9
- private AdapterPackageMarker() {}
10
- }
@@ -1,11 +0,0 @@
1
- #import <Foundation/Foundation.h>
2
-
3
- /**
4
- * Package marker so the podspec has a compilable source file.
5
- * Mediation is linked via the GoogleMobileAdsMediationFacebook pod dependency.
6
- */
7
- @interface RNGoogleMobileAdsAdapterFacebookMarker : NSObject
8
- @end
9
-
10
- @implementation RNGoogleMobileAdsAdapterFacebookMarker
11
- @end