firebase / flutterfire

🔥 A collection of Firebase plugins for Flutter apps.
https://firebase.google.com/docs/flutter/setup
BSD 3-Clause "New" or "Revised" License
8.68k stars 3.97k forks source link

[ad_mob] dispose does not dispose BannerAd if called before being loaded on Android #96

Closed alextekartik closed 3 years ago

alextekartik commented 5 years ago

Describe the bug On Android, If BannerAd.dispose() is called quickly after the BannerAd.show() is called, the banner might still be shown and can never be hidden

To Reproduce It is easier to reproduce by code (simple call show() then dispose()) but the example app should be enough Steps to reproduce the behavior:

  1. Build and run (flutter run) AdMob example app, can be on an emulator using test ads (although easier to reproduce on real device)
  2. Tap 'SHOW BANNER' then 'REMOVE BANNER' right away (the more the speed is like a double click, the more it might show the issue)
  3. If you did not manage to tap 'REMOVE BANNER' before the ad appears, the ad will be hidden correctly. Otherwise the ad might still appear (a little bit later - once loaded) and 'REMOVE BANNER' will never remove it.
  4. It might have worked as expected, otherwise try again multiple times, you might get to a point where 'REMOVE BANNER' can no longer hide the ad.

Expected behavior Calling dispose() should dispose the ad and prevent it from being shown later.

Additional context There seems to be an edge case condition in Android state machine where the ad view can be inserted in the tree once loaded - although adView.destroy() [java] has been called - but maybe that is not enough, some Android aps also hide the view (maybe add a new destroyed state to handle if the ad gets loaded later to prevent adding the child adView).

The workaround I have currently is that I wait (30s) for any event (loaded/load failure) before calling dispose on the dart land.

I have not tested on iOS (or at least not seen such issue)

If needed, I can work on a fix (just add this new destroyed state on Android) and submit a PR, let me know

LouisParkin commented 5 years ago

By managing the loaded state of the ads, I manage to get it to work correctly on Android, but on iOS, calling dispose appears to pop banners off a stack, rather than popping the one for which a reference is provided.

hesyar commented 4 years ago

@LouisParkin how did you solve this by managing the state?

LouisParkin commented 4 years ago

@hesyar I posted one of my dart files here: https://gist.github.com/LouisParkin/9e669b533f404c940d256fdb9af87afe ^ This one has the implementation of the banner And another here https://gist.github.com/LouisParkin/3f16687443c3b1e15507648ccf84161c ^This one has the state-managed disposal of a banner.

hesyar commented 4 years ago

@LouisParkin thanks a lot ;) I will check this in the evening

blasten commented 4 years ago

Another race condition: #669

russellwheatley commented 3 years ago

The firebase_admob plugin will be deprecated in April 2021 in favor of Google Mobile Ads SDK for Flutter. Google Mobile Ads SDK for Flutter is a new Flutter plugin that supports more Ads formats than firebase_admob does. Google Mobile Ads SDK for Flutter currently supports loading and displaying banner, interstitial (full-screen), native ads, and rewarded video ads across AdMob and AdManager. It also supports displaying banner and native ads as Widgets as opposed to being overlayed over all app content. We're now recommending projects currently using firebase_admob migrate to Google Mobile Ads SDK for Flutter following the instructions outlined here. Issues with migrating or with using the new package should now be raised over on the Google Mobile Ads SDK for Flutter repository.