marcojak / MauiMTAdmob

MIT License
104 stars 17 forks source link

Banner Ad not shown until leaving then returning to page (Android only) #64

Closed AntHillOracle closed 4 months ago

AntHillOracle commented 4 months ago

Banner Ad not shown until leaving then returning to page. This happens in Android only, iOS working as expected. On iOS I see the banner ads immediately on page load.

The banner does not appear on the page’s initial load, but when I navigate to a page ‘down the stack’ and then return to the page via the ‘move back’ button, the Ad then appears. I have tried this on three different pages and get the same result.

I do see the following debugger message upon first loading the page with banner: [Ads] JS: The jsLoaded GMSG has been sent … … [FA-Ads] Analytics storage consent denied; will not get app instance id

If I then advance to the next page and return back, the page is shown with the banner, and I get the following: [Ads] This request is sent from a test device. [Ads] Invoke Firebase method getInstance error. [Ads] The Google Mobile Ads SDK will not integrate with Firebase. Admob/Firebase integration requires the latest Firebase SDK jar, but Firebase SDK is either missing or out of date [Ads] JS: The jsLoaded GMSG has been sent …

I have not had Firebase in my project, as I don’t need its measurements. I have Xamarin.Firebase.iOS.Core in the project as a transitive package. I added Xamarin.Firebase.Core to the project, but this didn’t change anything.

I have the following Ad-related NuGet packages in my project (as transitive packages): Xamarin.Google.iOS.MobileAds Xamarin.GooglePlayServices.Ads.Base Xamarin.GooglePlayServices.Ads.Identifier Xamarin.GooglePlayServices.Ads.Lite

Here is some info about my code: I am using the MTAdView declared in XAML. I do not have a plug-in license. My MTAdView has the x:Name=”bannerAd”.

In my xaml code-behind, I have: protected override void OnAppearing() { base.OnAppearing(); bannerAd.LoadAd(); } I’ve tried placing this LoadAd() call in other locations but get the same results.

Android::MainActivity.cs public class MainActivity : MauiAppCompatActivity protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); CrossMauiMTAdmob.Current.Init(this, "My publisher id here"); } protected override void OnResume() { base.OnResume(); CrossMauiMTAdmob.Current.OnResume(); } }

My AndroidManifest.xml contains the following lines: meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="My publisher id here" meta-data android:name="com.google.android.gms.ads.DELAY_APP_MEASUREMENT_INIT" android:value="true" meta-data android:name="com.google.android.gms.ads.flag.OPTIMIZE_INITIALIZATION" android:value="true" meta-data android:name="com.google.android.gms.ads.flag.OPTIMIZE_AD_LOADING" android:value="true"

I’ve tried eliminating the final three lines here, but nothing changed.

Thanks for the help!

marcojak commented 4 months ago

With the new version (because of the Consent required before showing any ads) it's expected that you call LoadAd the first time, then it should work. If it doesn't, try to subscribe to these events: AdsClosed="MyAds_AdVClosed" AdsFailedToLoad="MyAds_AdFailedToLoad"

This should tell you if the banner has been loaded or if the loading failed. Let me know how it goes. Meanwhile I'll see if there is an issue in the plugin and if so, I'll fix it

AntHillOracle commented 4 months ago

I definitely have been calling LoadAd(). I've tried placing that call in the page's constructor and in OnAppearing(), but it doesn't change the behavior. What I have performs correctly on iOS.

I'll subscribe to those events and see what I see.

marcojak commented 4 months ago

I've tested it and it with the sample and it works. My current idea is that you might call the loadAd before the Mobile ads has been actually initialised. Out of curiosity, while we identify a proper solution...could you add a delay of 4-5 seconds before loading the ads?

I'm working on a new version, and I'll probably add an event for when the mobile ads has been initialised.

On Wed, 7 Feb 2024, 23:46 AntHillOracle, @.***> wrote:

I definitely have been calling LoadAd(). I've tried placing that call in the page's constructor and in OnAppearing(), but it doesn't change the behavior. What I have performs correctly on iOS.

I'll subscribe to those events and see what I see.

— Reply to this email directly, view it on GitHub https://github.com/marcojak/MauiMTAdmob/issues/64#issuecomment-1933060689, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAUIPIRYRCSRZTFRR4I64C3YSP75DAVCNFSM6AAAAABC6RXJW6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMZTGA3DANRYHE . You are receiving this because you commented.Message ID: @.***>

AntHillOracle commented 4 months ago

Adding a delay before (or after) the call to LoadAds() didn't have any effect. I still don't get a banner until I leave the page and come back to it. Thanks, Marco.

AntHillOracle commented 4 months ago

It's not clear to me what events you wished me to subscribe to. There doesn't appear to be an available AdsClosed or AdsFailedToLoad event. The closest name is OnAppOpenFailedToLoad. In your sample it doesn't appear that your MyAds_AdVClosed or MyAds_AdFailedToLoad handlers are wired to anything?

I turned my Interstitial Ad code back on, and I am getting Interstitials as expected and those event are firing into my handlers.

marcojak commented 4 months ago

If you look at the sample code, you'll see the events in the MainPage in the MTAdView control

AntHillOracle commented 4 months ago

If you look at the sample code, you'll see the events in the MainPage in the MTAdView control

Ok, I see the events in the xaml. All of the event wiring for interstitials in the code-behind fooled me into expecting it there.

So I wired up the events -- On Android, no event is fired until leaving the page and returning, upon which "AdsLoaded" is fired and the banner appears. "AdsFailedToLoad" or "AdsClosed" events are not received by my handlers.

On iOS, the banners are working fine, but events on banners are never caught, including "AdsLoaded" and "AdsOpened" for live banners that are clicked on. Interstitial events are working on iOS.

This is a MAUI .NET 8 project.

AntHillOracle commented 4 months ago

Question: How is one intended to show a banner ad without requiring the user to click on a 'load banner' button?

I've been messing with the MMTAdmobSample. I added the 'myAds.LoadAd()' call from the 'load banner' button event handler to the MainPage constructor. No ad appears, I tried some other things, but it seems the only way to get a banner to appear is to use the button click interaction.

Next, I added a new ContentPage and repurposed your 'Next Page' button to perform an 'await Navigation.PushModalAsync(new NextPage());' to the new page. My NextPage has a banner ad control, a button to PopModal, and a button to Push another NextPage.

On the NextPage, the banner ad appears with the page load on iOS, but does not appear on Android.

marcojak commented 4 months ago

I still believe that when you call the loadAd in the constructor, the MobileAds hasn't been initialized yet but to be sure, let me do a test on the MMTAdmobSample and I'll update you on what's happening. It should work on both Android and iOS. If it doesn't it might be a bug. I'm currently working to add the NativeAds but I'm planning to bring back the auto load for the banners doing automatically the check on the consent. Anyway, for now, let me see what's going on with the banner

marcojak commented 4 months ago

Ok, I've identified the issue. I'll add it to the guide to explain how it should work, however in the next version, I'll also try to automatically load the banner.

Coming back to the issue. There are actually 2 issues here (not with the plugin but with how MAUI works):

1) If you call "myAds.LoadAd();" in the constructor, the related handler is not initialised yet, so nothing can happen. 2) if you delay the call but don't call it from the MainThread it will not work and will block any future call to LoadAds.

There are 2 options you can use, according to your preferences:

1) In your OnAppearing method you can add this code:

 Task.Run(async () =>
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    myAds.LoadAd();
                });
            });

At that time the Handler SHOULD (not certain but from my quick tests on a Pixel 7PRO it always was) be initialized and the BeginInvokeOnMainThread forces the call on the MainThread. This should work and you'll be able to see the Banner.

2) You subscribe (IN XAML or C#) to the event HandlerChanged

HandlerChanged="myAds_HandlerChanged"

and in your C# you can simply load the banner:

private void myAds_HandlerChanged(object sender, EventArgs e)
   {
       myAds.LoadAd();
   }

In this case the Handler has been initialised and the load will happen correctly.

AntHillOracle commented 4 months ago

Thanks for the update/info! Using the event handler as per option 2 works for me.

It would be cool if banners automatically loaded, just so we don't need to spread this boilerplate code around (notably this code isn't needed on iOS).

marcojak commented 4 months ago

Yesterday I've released version 1.3.0.

This version automatically loads the banner after checking the consent (for the licensed version) or after the mobile ads initialisation for the non licensed version.

Closing it for now but feel free to open it again if you are having issues with it

AntHillOracle commented 4 months ago

This is still not working ideally with 1.3.0. The ‘front page’ of my app works fine – it gets its banner loaded without any bannerAd.LoadAd() or HandlerChanged event code. But upon navigating to a page down the stack, the banner will not load on the first appearance of the page without implementing a handler for the HandlerChanged event and there calling bannerAd.LoadAd(). On these subsequent pages a banner will eventually load without the extra code if you navigate down from the page and then return back to it – which is how version 1.2 performed.

I'm not seeing how to re-open the issue, so I'll leave that to you.

Thanks for the effort.

marcojak commented 4 months ago

Thinking about it, you are right. The code works for the first page but the loading doesn't happen in the others as the events I've used to see if we can actually load the banner are not invoked anymore. I'll fix it in the next version.

marcojak commented 4 months ago

I've just released version 1.3.1 which should fix this issue. It should be available soon

AntHillOracle commented 4 months ago

That did the trick. All is working now. Thanks much!