zoontek / react-native-bootsplash

🚀 Show a splash screen during app startup. Hide it when you are ready.
MIT License
3.72k stars 256 forks source link

Broken behavior with Google Admob App Open Ads in 5.1.0+ #512

Closed andkom closed 11 months ago

andkom commented 12 months ago

Bug summary

version 5.1.0+ breaks compatibility with react-native-google-mobile-ads package's app open Ads.

AppOpenAd hides the splash screen while it is displayed.

5.0.4 behavior (expected):

App open => Splash shown => Ad shown over splash => Ad closed => Splash hidden => Main screen shown

5.1.0+ behavior (actual):

App open => Splash shown => Splash hidden => Ad shown over main screen => Ad closed => Splash shown => Splash hidden => Main screen shown

Library version

5.1.2

Environment info

OS: Android
Devices: Android Emulator SDK 31, Samsung Galaxy S21 

  "dependencies": {
    "react": "18.2.0",
    "react-native": "0.72.7",
    "react-native-bootsplash": "5.1.2",
    "react-native-google-mobile-ads": "12.3.0"
  }

Steps to reproduce

  1. Use sample code from https://github.com/andkom/rn-admob-bootsplash
  2. Open app
  3. the splash is hidden when AppOpenAd is displayed

Change react-native-bootsplash version to 5.0.4

  1. rebuild app
  2. Open app
  3. AppOpenAd is displayed over the splash (as expected)

Reproducible sample code

import React, {useCallback, useEffect, useState} from 'react';
import {Text} from 'react-native';
import BootSplash from 'react-native-bootsplash';
import mobileAds, {
  MaxAdContentRating,
  TestIds,
  useAppOpenAd,
} from 'react-native-google-mobile-ads';

mobileAds()
  .setRequestConfiguration({
    maxAdContentRating: MaxAdContentRating.PG,
    tagForChildDirectedTreatment: true,
    tagForUnderAgeOfConsent: true,
    testDeviceIdentifiers: ['EMULATOR'],
  })
  .then(() => {
    // Request config successfully set!
  });

function App() {
  const [splashHidden, setSplashHidden] = useState(false);
  const {load, isLoaded, error, show, isClicked, isClosed} = useAppOpenAd(
    TestIds.APP_OPEN,
  );

  const hideSplash = useCallback(async () => {
    await BootSplash.hide({fade: true});
    setSplashHidden(true);
  }, []);

  useEffect(() => {
    load();
    console.log('Start loading ad');
  }, [load]);

  useEffect(() => {
    if (isLoaded && !splashHidden) {
      show();
      console.log('Ad shown!');
    }
  }, [isLoaded, splashHidden, show]);

  useEffect(() => {
    (async () => {
      if (isClosed || isClicked) {
        await hideSplash();
        console.log('Splash hidden because ad is closed or clicked!');
      }
    })();
  }, [isClosed, isClicked, hideSplash]);

  useEffect(() => {
    const init = async () => {
      // …do multiple sync or async tasks
      await new Promise(resolve => setTimeout(resolve, 5000));
      console.log('Init complete!');
    };

    init().finally(async () => {
      if (!isLoaded || error) {
        await hideSplash();
        console.log('Splash hidden because ad is not loaded or error!');
      }
    });
  }, [hideSplash]);

  return <Text>My awesome app</Text>;
}

export default App;
zoontek commented 12 months ago

@andkom Thanks for the reproduction repository, but unfortunately I can't make it work. I get [Error: [googleMobileAds/no-fill] Ad unit doesn't match format. <https://support.google.com/admob/answer/9905175#4>

andkom commented 12 months ago

@zoontek what is your screen size? Try to use Android Emulator and Google Pixel 3a.

Also stackoverflow says:

To answer the question:

NO_FILL is returned from AdMob when there is no inventory left to serve in the AdMob/DFP backend.

First of all this meant I was requesting an ad of size AxB, but the backend had no ads of this size left to show. It is important that the size you request has inventory left in the backend systems of AdMob/DFP.

Second, their API states that the first time you request an ad to a specific ad unit, you should expect up to two minutes before the ads start serving. I don't know if it is because I am not stationed in the US, but these two minutes often becomes at least 20 minutes if not several hours for me.

zoontek commented 11 months ago

@andkom I created a new emulator, Android 13, Google Pixel 3a and get the exact same issue.

zoontek commented 11 months ago

It should fix it: https://github.com/zoontek/react-native-bootsplash/releases/tag/5.1.3 I'm still interested to making the reproduction work, this way I will be able to check / debug this use case in futures releases.

andkom commented 11 months ago

Unfortunately, AppOpen Ads stopped working in the example and in the main application in dev environment. The cause is unknown. It works only in release environment.

andkom commented 11 months ago

I found the cause, Google has changed their AppOpen Ad test Unit ID. I updated repository and can confirm v5.1.3 works as expected.