react-native-admob icon indicating copy to clipboard operation
react-native-admob copied to clipboard

two AdMobInterstitial load problem (!!CRASH!!) !!! ----> Thread 1: EXC_BAD_ACCESS (code=1,address=0x10)) _requestAdResolve(nil);

Open furkancelik opened this issue 8 years ago • 6 comments

hi, I have nested components in AdMobInterstitial ads.

component1 (Game.js)

import React, { Component } from "react";
import {...} from "react-native";
import Header from "../../Components/Game/Header";
...
...
import {
  AdMobInterstitial
} from "react-native-admob";


export default class Game extends Component {
   static navigationOptions = {
     header: props => <Header {...props} />,
     gesturesEnabled: false
   };
  
  componentDidMount() {
  

    AdMobInterstitial.setTestDevices([AdMobInterstitial.simulatorId]);
    AdMobInterstitial.setAdUnitID("ca-app-pub-XXXXXXXXXXXX/XXXXXX");

    AdMobInterstitial.addEventListener("adLoaded", () => {
      console.log("AdMobInterstitial adLoaded");
    });
    AdMobInterstitial.addEventListener("adFailedToLoad", error =>
      console.warn(error)
    );
    AdMobInterstitial.addEventListener("adOpened", () =>
      console.log("AdMobInterstitial => adOpened")
    );
    AdMobInterstitial.addEventListener("adClosed", () => {
      console.log("AdMobInterstitial => adClosed");

      AdMobInterstitial.requestAd().catch(error => console.warn(error));
    });
    AdMobInterstitial.addEventListener("adLeftApplication", () =>
      console.log("AdMobInterstitial => adLeftApplication")
    );

    AdMobInterstitial.requestAd().catch(error => console.warn(error));

    AppStore.setShowInterstitial(this.showInterstitial);
  }

  componentWillUnmount() {
    AdMobInterstitial.removeAllListeners();
  }

  showInterstitial() {
    AdMobInterstitial.showAd().catch(error => console.warn(error));
  }

 



  endGame() { this.showInterstitial(); }
  render() {
    return (
          .....
    );
  }
}

EndGame show Interstitial ads.

component2 (Header.js)

import React, { Component } from "react";
import {... } from "react-native";
....
....
import { NavigationActions } from "react-navigation";

import {
  AdMobInterstitial
} from "react-native-admob";


export default class Header extends Component {
componentDidMount() {
  

    AdMobInterstitial.setTestDevices([AdMobInterstitial.simulatorId]);
    AdMobInterstitial.setAdUnitID("ca-app-pub-XXXXXXXXXXXX/XXXXXX");

    AdMobInterstitial.addEventListener("adLoaded", () => {
      console.log("AdMobInterstitial adLoaded");
    });
    AdMobInterstitial.addEventListener("adFailedToLoad", error =>
      console.warn(error)
    );
    AdMobInterstitial.addEventListener("adOpened", () =>
      console.log("AdMobInterstitial => adOpened")
    );
    AdMobInterstitial.addEventListener("adClosed", () => {
      console.log("AdMobInterstitial => adClosed");

      AdMobInterstitial.requestAd().catch(error => console.warn(error));
    });
    AdMobInterstitial.addEventListener("adLeftApplication", () =>
      console.log("AdMobInterstitial => adLeftApplication")
    );

    AdMobInterstitial.requestAd().catch(error => console.warn(error));

    AppStore.setShowInterstitial(this.showInterstitial);
  }

  componentWillUnmount() {
    AdMobInterstitial.removeAllListeners();
  }

  showInterstitial() {
    AdMobInterstitial.showAd().catch(error => console.warn(error));
  }


  render() {
    const { coin, showInterstitial } = AppStore;
    return (....
      <TouchableOpacity onPress={()=>{this.showInterstitial()}}><Text>Back Page</Text></ToıchableOpacity>
    ....);
  }
}

header, back page click show Interstitial ads.

error: ekran resmi 2018-04-07 16 10 25

what could be the cause of the problem???

furkancelik avatar Apr 07 '18 15:04 furkancelik

You're requesting the ad while it's already loaded. set adLoaded to the state from eventListener then request if it's not loaded!

ossamaweb avatar Jun 08 '18 23:06 ossamaweb

I'm having the same problem.. I can't fix it

ghost avatar Jun 30 '18 12:06 ghost

I am having the exact same problem only in Xcode simulator but on the device it works fine... can someone explain more the solution?

smcox13 avatar Feb 24 '19 16:02 smcox13

i have this problem too

tahakhozooie avatar Mar 27 '19 09:03 tahakhozooie

Could someone solve this problem?

tahakhozooie avatar Apr 07 '19 13:04 tahakhozooie

I had this exact issue as well, but did find that preloading the next interstitial on adClosed worked quite well. Here's an example of what I have in use now:

const [adLoaded, setLoaded] = useState(false)
const { myTrigger } = props

const requestAd = () => AdMobInterstitial.requestAd().catch(_error => setLoaded(false))

AdMobInterstitial.addEventListener('adLoaded', () => setLoaded(true))
// preload next ad after interstitial is consumed
AdMobInterstitial.addEventListener('adClosed', () => requestAd())

// show preloaded ad once the trigger is hit
useEffect(() => {
  if (myTrigger) {
    AdMobInterstitial.showAd().catch(error => console.log(`ShowAd: ${error}`))
  }

  // load on component mount and any state change, when needed
  if (!adLoaded) {
    requestAd()
  }

  return function cleanup() {
    AdMobInterstitial.removeAllListeners()
  }
})

return (
  adLoaded ? <AfterAdComponent /> : <LoadingComponent />
)

This will preload the ad, and when the trigger is hit, show the ad. If the ad isn't ready when it's time to show (which causes the crash), it instead shows the LoadingComponent until the ad is loaded, and then shows the ad. You shouldn't see the LoadingComponent unless the ad is loaded too quickly, otherwise it will simply transition into the ad, and then render the AfterAdComponent without any crashes.

I hope someone else can make as much use of this, as I did. 👍

LAST EDIT: Updated to pattern so that it works with the edge case where re-triggering too fast causes it to show the ad before it's ready.

MutableLoss avatar May 15 '20 01:05 MutableLoss