App Crashes onAdFailedToLoad or Ad yet to load

30 Views Asked by At

I have rewarded ads set set up via google admob.

Issue: I am presently having issues which results in the app crashing on instances where ads are yet to load.

What has been done:

I implemented a setTimeOut for a second delay before showing ads, this has considerably reduced the crash, but I highly doubt that's sustainable as I am yet to gain an understanding of the underlying issue.

I had also attempted to use useState to identify when adLoad is truthy but that seems to be ineffective in actually identifying when ads have loaded.

useEffect(() => {
console.log('ads loaded', loaded)
}, [loaded])

The above only runs once with a false. despite been able to see ads after delay. (see below). so this has proved ineffective.

Here's the full code:

import {
 RewardedAd,
 TestIds,
 AdEventType,
 RewardedAdEventType 
} from 'react-native-google-mobile-ads';

const adUnitId = __DEV__ ? TestIds.REWARDED 
: 'ca-app-pub-xxxxxxxxxxxxxxxxxxx';


const rewarded = RewardedAd.createForAdRequest(adUnitId, {
    requestNonPersonalizedAdsOnly : false,
    keywords: ['finance', 'Accounting', ],
});

const AdScreen = ({ navigation }) => {

    const [loaded, setLoaded] = useState(false);
    const adRewardEarnedRef = useRef(null)

 useEffect(() => {
        const unsubscribeLoaded = rewarded.addAdEventListener(
            RewardedAdEventType.LOADED,
            () => {
                setLoaded(true);

            },
        );
        const unsubscribeEarned = rewarded.addAdEventListener(
            RewardedAdEventType.EARNED_REWARD,
            () => {
                adRewardEarnedRef.current = 'earned'  // 

            },
        );



        const unsubscribeAdsClosed = rewarded.addAdEventListener(
            AdEventType.CLOSED,
            () => {
                if (adRewardEarnedRef.current != null) {
                    setTimeout(() => {
                        setBottomModalVisible(true)
            
                    }, 500)
                }
            }
        )

        const unsubscribeAdsFailedToLoad = 
          rewarded.addAdEventListener(
            AdEventType.ERROR,
            () => {
                console.log('error')
           //I couldn't get anything worthwhile from this call. 
// only proved useful on instances where there's no consent
            }
        )


        rewarded.load();


        return () => {
            unsubscribeAdsClosed();
            unsubscribeLoaded();
            unsubscribeEarned();
            unsubscribeAdsFailedToLoad();
        };
    }, []);


 const watchAdToDownload = () => {
        setModalVisible(false)
        setTimeout(() => {
            rewarded.show()
        },1000)
    }

    const handleNavigateToGoPro = () => {
        setModalVisible(false)
        navigation.navigate("GoProScreen")
    }

    const handleDownloadButton = () => {
        if (paidUser) {
            return setBottomModalVisible(true)
        }

        if (adRewardEarnedRef.current != null) {
            return setBottomModalVisible(true)
        }
       
        setModalVisible(true)
    }



}

Any suggestions on how to resolve this??

On a side note:

I am thinking of a preload approach, but unsure about its implementation. i.e loading the ad in the previous screen and then navigating to a new screen, ads can show, will that be possible?

1

There are 1 best solutions below

0
abic17 On

On further research, here's a solution (Using Hooks):

export function adMobRewardedAds() {
    const { isLoaded, load, show } = useRewardedAd(TestIds.REWARDED, {
      requestNonPersonalizedAdsOnly: true,
      keywords: ['xx'],
    });
  
    useEffect(() => {
        console.log('isLoaded: ',isLoaded)
      if (!isLoaded) {
        load();
      }
    }, [isLoaded, load]);
  
    const openAd = () => {
       if (isLoaded) {
        show();
       }
    };
  
    return {
      isLoaded,
      openAd,
    };
  }

Then the component or screen you intend to use it:

import { adMobRewardedAds } from '../hooks/useAdMobRewardedAds';

'blah blah blah'

    const { isLoaded, openAd } = adMobRewardedAds();


      <TouchableOpacity onPress={openAd()}>
         <Text> Click <Text>
     </TouchableOpacity>

This is just a template, ensure to add additional error handling etc.

Solution was found here... https://github.com/invertase/react-native-google-mobile-ads/issues/400#issuecomment-1660581891