react-native-google-mobile-ads
react-native-google-mobile-ads copied to clipboard
AppOpenAd is launched after interstitial is closed
The recommended way to launch an AppOpenAd is through the app state when the app comes from the background. However, when an Interstitial Ad is closed, that is also recognized as an app state change, and it triggers the AppOpenAd. Has anyone found a good workaround?
Check if the previous state was "background".
On Android It's always considered background, whether you close a modal or open the app from background.
On Sun, Mar 20, 2022, 19:14 Dylan @.***> wrote:
Check if the previous state was "background".
— Reply to this email directly, view it on GitHub https://github.com/invertase/react-native-google-mobile-ads/issues/102#issuecomment-1073238337, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGGIDCV7QKD2AKWJ5KCEYLLVA4JC5ANCNFSM5RFJJTWA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
You are receiving this because you authored the thread.Message ID: @.*** com>
True, a modal is actually a system window and is separate from the app, so I guess it is mis-diagnosing even "mild backgrounding" (being overlayed by a system modal) as full background. Android has multiple lifecycle steps in activities, not foreground/background - it has a sequence of pre-start/start/post-start for the application and the MainActivity, then it has pre-resume/resume/post-resume, on the way up. On the way down it's pre-/pause/post- then pre-/stop/post- hooks
https://developer.android.com/reference/android/app/Application.ActivityLifecycleCallbacks.html
This package is just one that turned up in search and looks abandoned but I wonder if something like it listening in MainActivity for the pause vs the stop might be able to differentiate? https://github.com/jaysoo/react-native-activity-android
I can only suggest careful experimentation, I have a lot of Android experience personally but have never played in this area with react-native to see how it reacts to these sort of state changes and what lifecycle observer events are emitted or what lifecycle state changes it goes through - they aren't exposed by AppState API though, I just checked
Seems related to: https://github.com/googleads/googleads-mobile-flutter/issues/404 We basically need a RN version of https://github.com/ajinasokan/flutter_fgbg
Oh that's really interesting @dylancom ! If I understand correctly I can summarize that issue as:
- currently an interstitial (perhaps any full screen) ad is part of our application but it is not part of the activity
- when the activity goes into the background (Android onPause maybe onStop) to show the ad then the ad finishes and onStart/onResume lifecycle stuff happens, that triggers AppState in a way that the AppOpen ad shows?
So the solution here for App Open ads is to listen to Application lifecycle events, not Activity lifecycle events?
If so, that is actually really easy believe it or not. The infrastructure to expose them to JS (if needed) via an event emitter is somewhat more complex but I think the code from react-native-firebase common which we ingested here may even make that easy ?
@wjaykim I hope you can make an AppOpen Provider similar to the Admob library you did. This will make it simple for those with little experience to implement AppOpen. Thanks.
@mikehardy In previous library (@react-native-admob/admob) there was code listening for application lifecycle events: https://github.com/react-native-admob/admob/blob/4b24e57308aa2dd0e28a6eab1d90ae81576e69b2/android/src/main/java/com/rnadmob/admob/ads/fullscreen/RNAdMobAppOpenAdModule.java#L115-131
But should the part be implemented in this library? I think it should be implemented in different library(that sends event for application lifecycle event).
I think we should implement them here, my reasoning:
- the app lifecycle events are trivial to implement, it's simple native code
- how we handle them is so tightly coupled to this library
- we don't need JS bindings I don't think? Even in the code you link it's not a ReactMethod, which means we don't really need a react-native package we just need to hook the Android APIs and respond.
That's my analysis of it anyway - I'd be excited to merge a PR that was basically java-only and listened to Android lifecycle events in order for AppOpen to behave well. But I could be wrong! I'm open to any other thoughts
I agree that we should implement it here as it's very tightly coupled. They also did that in the official flutter package last year: https://github.com/googleads/googleads-mobile-flutter/issues/404
I faced a similar issue and this is how I fixed it.
We know that everytime an interstitial ad is closed, AppOpenAd will show as soon as AppState event fires.
const AdState = {
canShowAppOpenAd:true
};
// In some useEffect hook
InterstitialAd.addAdEventListener(AdEventType.CLOSED, () => {
// Do not allow AppOpenAd to show right after InterstitialAd is closed.
// We can depend on this as it's called soon enough before AppState event fires.
AdState.canShowAppOpenAd = false;
});
// Showing AppOpenAd
AppState.addEventListener("change", async (state) => {
if (state === "active") {
if (
AppOpenAd.loaded &&
AdState.canShowAppOpenAd
) {
AppOpenAd.show();
} else {
//Reset AdState so next time user enters from the true background state, the AppOpenAd shows.
AdState.canShowAppOpenAd = true;
}
}
})
I hope this helps someone. It works perfectly fine.
Oh that's funny - but in a good way! I mean of course (not that I thought of it) that's a perfect workaround. We should still handle what I think of as an error in state detection correctly in the library for real though. Until then, very nice workaround, thanks for posting that
As a TEMPORARY fix, I created a module for android, it worked fine instead of AppState react-native-activity-state But I'm not done for IOS yet
Fantastic @quan2nd I'm not sure that iOS has the same issues, does it? For Android though, the code looks good - we could take a PR here if you wanted, or I suppose it could be a separate module (perhaps others have this same need?) although that would complicate our install a little bit by having this module depend on another one being installed
@quan2nd on iOS we can just rely on if the previous appState was "background".
Hello 👋, to help manage issues we automatically close stale issues.
This issue has been automatically marked as stale because it has not had activity for quite some time.Has this issue been fixed, or does it still require attention?
This issue will be closed in 15 days if no further activity occurs.
Thank you for your contributions.
So did yall get an actual solution for this?
I faced a similar issue and this is how I fixed it.
We know that everytime an interstitial ad is closed,
AppOpenAdwill show as soon asAppStateevent fires.const AdState = { canShowAppOpenAd:true }; // In some useEffect hook InterstitialAd.addAdEventListener(AdEventType.CLOSED, () => { // Do not allow AppOpenAd to show right after InterstitialAd is closed. // We can depend on this as it's called soon enough before AppState event fires. AdState.canShowAppOpenAd = false; }); // Showing AppOpenAd AppState.addEventListener("change", async (state) => { if (state === "active") { if ( AppOpenAd.loaded && AdState.canShowAppOpenAd ) { AppOpenAd.show(); } else { //Reset AdState so next time user enters from the true background state, the AppOpenAd shows. AdState.canShowAppOpenAd = true; } } })I hope this helps someone. It works perfectly fine.
this works only some time and for one screen. but not working for full app