Appliquer les réglages RGPD de Google AdMob dans React Native (Android)

AdMob continue d’avertir l’utilisateur d’afficher des messages relatifs au RGPD.

Étant donné que la création de messages RGPD dans AdSense était simple, j’ai supposé que ce serait la même chose pour AdMob. Toutefois, AdMob nécessitait du code supplémentaire dans l’application pour vérifier directement le consentement. 😱

Prérequis

❗Je n’assume aucune responsabilité légale. ❗

J’ai implémenté cela sur la base de la documentation Google, d’exemples de codes et de recherches. Cependant, il peut y avoir des interprétations incorrectes concernant les politiques ou leur mise en œuvre. Veuillez l’utiliser uniquement à titre de référence.

A vous de vous assurez que le code fonctionne normalement en Europe.

Configuration des messages RGPD

Accédez à Google AdMob > Confidentialité et messages > Cliquez sur Réglementations européennes > Créer un message.

Configurez les paramètres en fonction de votre application.

Après avoir créé et publié le message, vous devez implémenter le code pour que le message RGPD configuré soit affiché.

Mise en oeuvre sur React native

Pour la suite de cet article, j’ai repris le code du projet qui a été mise en place dans l’article Intégrer Google ads dans une application mobile avec React native et Expo pour Android et iOS.

Dans app.json

{
  "expo": {
    
  },
  "react-native-google-mobile-ads": {
    "android_app_id": "ca-app-pub-xxxxxxxx~xxxxxxxx"
    "delay_app_measurement_init": true
  }
}

Ajouter le fichier /utils/rgpdConsent.ts

// https://docs.page/invertase/react-native-google-mobile-ads/european-user-consent
import mobileAds, {AdsConsent, AdsConsentDebugGeography} from 'react-native-google-mobile-ads';

const debugParams = {
  debugGeography: AdsConsentDebugGeography.EEA,
  testDeviceIdentifiers: ['Your-Test-Device-Hashed-Id'],
}

// Initialize AdsMob
function initializeMobileAdsSdk() {
  mobileAds()
    .initialize()
    .then(adapterStatuses => {
      console.log("mobileAds initialize:", adapterStatuses);
    });
}

// Check consent status
async function checkIsNotAgreement() {
  const {
    activelyScanDeviceCharacteristicsForIdentification,
    applyMarketResearchToGenerateAudienceInsights,
    createAPersonalisedAdsProfile,
    createAPersonalisedContentProfile,
    developAndImproveProducts,
    measureAdPerformance,
    measureContentPerformance,
    selectBasicAds,
    selectPersonalisedAds,
    selectPersonalisedContent,
    storeAndAccessInformationOnDevice,
    usePreciseGeolocationData,
  } = await AdsConsent.getUserChoices();

  return (
    applyMarketResearchToGenerateAudienceInsights === false ||
    createAPersonalisedAdsProfile === false ||
    createAPersonalisedContentProfile === false ||
    developAndImproveProducts === false ||
    measureAdPerformance === false ||
    measureContentPerformance === false ||
    selectBasicAds === false ||
    selectPersonalisedAds === false ||
    selectPersonalisedContent === false ||
    storeAndAccessInformationOnDevice === false ||
    usePreciseGeolocationData === false
  )
}

async function requestConsent() {
  return await AdsConsent.requestInfoUpdate();
  //return await AdsConsent.requestInfoUpdate(debugParams); // Add debugParams during testing
}

// Load GDPR consent form and check consent status
export async function loadGdprAdsConsent(
) {
  try{
    //await AdsConsent.reset(); // Uncomment for testing
    const data = await requestConsent();

    if(data.isConsentFormAvailable){
      const resultForm = await AdsConsent.loadAndShowConsentFormIfRequired();

      // If the user has already consented or refused consent, check the consent status and request consent if needed
      if(data.status === 'OBTAINED'){
        const isNotAgreement = await checkIsNotAgreement();

        if(isNotAgreement) {
          await AdsConsent.showForm();
        }
      }

      if(resultForm.canRequestAds === true) {
        initializeMobileAdsSdk()
      }
    } else {
      initializeMobileAdsSdk()
    }
  }
  catch(error) {
    console.log('loadGdprAdsConsent > error: ', error);
    initializeMobileAdsSdk();
  }
}

// Check if Consent is Available (EEA region)
export async function checkIsConsentAvailable() {
  try{
    const data = await requestConsent();
    //console.log('checkConsentAvailable > data: ', data);

    return data.isConsentFormAvailable;
  }catch (error) {
    console.log('checkConsentAvailable > error: ', error);
    return false;
  }
}

// Show consent form on button click or screen navigation, and check consent status afterward
export async function showAdsConsentForm(
  consentCallback?: () => void,
  notConsentCallback?: () => void,
) {
  try{
    const data = await requestConsent();

    if(data.isConsentFormAvailable){
      const isNotAgreement = await checkIsNotAgreement();

      if(isNotAgreement) {
        await AdsConsent.showForm();

        // Re-check consent status
        const isNotAgreementResult = await checkIsNotAgreement();

        if(isNotAgreementResult) {
          // Handle non-consent
          notConsentCallback && notConsentCallback();
        } else {
          // Handle consent
          consentCallback && consentCallback();
        }
      } else {
        // Handle consent
        consentCallback && consentCallback();
      }
    }
    else {
      // Handle case where no consent form is available
      consentCallback && consentCallback();
    }
  }catch (error) {
    console.log('showAdsConsentForm > error: ', error);
  }
}

// Show privacy options form in settings
export async function showPrivacyOptionsForm() {
  try{
    const data = await requestConsent();

    if(data.isConsentFormAvailable){
      await AdsConsent.showPrivacyOptionsForm()
    }
  }catch (error) {
    console.log('showPrivacyOptionsForm > error: ', error);
  }
}

App.js

import { StatusBar } from "expo-status-bar";
import React, { useEffect, useState } from "react";
import { StyleSheet, Text, View, TouchableOpacity } from "react-native";
import {
  loadGdprAdsConsent,
  checkIsConsentAvailable,
  showPrivacyOptionsForm,
} from "./utils/rgpdConsent";
import {
  BannerAd,
  BannerAdSize,
  TestIds,
} from "react-native-google-mobile-ads";

const adUnitId = __DEV__
  ? TestIds.ADAPTIVE_BANNER
  : "ca-app-pub-xxxxxxxxxxxxx/yyyyyyyyyyyyyy";

export default function App() {
  useEffect(() => {
    loadGdprAdsConsent()
      .then(() => {
        console.log("loadGdprAdsConsent completed");
      })
      .catch((err) => {
        console.log("loadGdprAdsConsent err: ", err);
      });

    checkIsConsentAvailable().then((isAvailable) => {
      setIsConsentAvailable(isAvailable);
    });
  }, []);

  const [isConsentAvailable, setIsConsentAvailable] = useState(false);

  return (
    <View style={styles.container}>
      <Text style={{ marginBottom: 10 }}>Google ads android</Text>
      <StatusBar style="auto" />
      <BannerAd
        unitId={adUnitId}
        size={BannerAdSize.ANCHORED_ADAPTIVE_BANNER}
      />
      <TouchableOpacity
        style={styles.listContainer}
        onPress={() => showPrivacyOptionsForm()}
      >
        <Text>Changer les paramètres RGPD</Text>
      </TouchableOpacity>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

Si le comportement de chargement est incorrect (par exemple, chargement alors qu’il ne devrait pas ou pas chargement alors qu’il le devrait) :

  • Les informations sélectionnées sont stockées dans le stockage local. La suppression du stockage de l’application et la relance ont résolu le problème.
  • Si l’étape ci-dessus ne fonctionne pas, en dernier recours, désinstallez l’application et réinstallez-la pour garantir un bon fonctionnement.