admob_flutter icon indicating copy to clipboard operation
admob_flutter copied to clipboard

Rewarded ads not showing

Open shinayser opened this issue 4 years ago • 25 comments

Hello!

The banners are working fine, but the rewarded, not showing up. This is my test code:

AdmobReward rewardAd = AdmobReward(
                        adUnitId: testRewardedId,
                        listener: (event, args) {
                          print('GOT EVENT $event com args: $args');
                        },
                      );
                      rewardAd.load();

                      if (await rewardAd.isLoaded) {
                        rewardAd.show();
                      }
                    },

My Log:

I/Ads     (21483): This request is sent from a test device.
I/AudioManager(21483): In isSpeakerphoneOn(), calling application: com.shinayser.tapthefab.app
I/ExoPlayerImpl(21483): Init ExoPlayerLib/2.4.2 [montana_n, Moto G (5S), motorola, 27]
D/MetadataUtil(21483): Skipped unknown metadata entry: gsst
D/MetadataUtil(21483): Skipped unknown metadata entry: gstd
W/VideoCapabilities(21483): Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities(21483): Unrecognized profile 2130706434 for video/avc
W/VideoCapabilities(21483): Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities(21483): Unrecognized profile 2130706434 for video/avc
W/VideoCapabilities(21483): Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities(21483): Unrecognized profile 2130706434 for video/avc
I/VideoCapabilities(21483): Unsupported profile 4 for video/mp4v-es
W/VideoCapabilities(21483): Unrecognized profile 2130706433 for video/avc
W/VideoCapabilities(21483): Unrecognized profile 2130706434 for video/avc
I/MediaCodec(21483): name=OMX.google.aac.decoder isType=false encoder=false
I/MediaCodec(21483): (0x7f273940) init name(OMX.google.aac.decoder) isType(0) encoder(0)
I/OMXClient(21483): Treble IOmx obtained
I/MediaCodec(21483): (0x7f273940) Component Allocated (OMX.google.aac.decoder)
I/MediaCodec(21483): (0x7f273940) configure surface(0x0) crypto(0x0) flags(0)
D/MediaCodec(21483): (0x7f273940) configure format: AMessage(what = 0x00000000) = {
D/MediaCodec(21483):       int32_t sample-rate = 44100
D/MediaCodec(21483):       string mime = "audio/mp4a-latm"
D/MediaCodec(21483):       int32_t channel-count = 2
D/MediaCodec(21483):       string language = "und"
D/MediaCodec(21483):       int32_t max-input-size = 547
D/MediaCodec(21483):       Buffer csd-0 = {
D/MediaCodec(21483):         00000000:  12 10                                             ..
D/MediaCodec(21483):       }
D/MediaCodec(21483):     }
W/ExtendedACodec(21483): Failed to get extension for extradata parameter
I/MediaCodec(21483): (0x7f273940) start
I/MediaCodec(21483): (0x7f273940) kWhatStartCompleted
D/MediaCodec(21483): (0x7f273940) kWhatOutputBuffersChanged
D/MediaCodec(21483): (0x7f273940) [OMX.google.aac.decoder] output format changed to: AMessage(what = 0x00000000) = {
D/MediaCodec(21483):       string mime = "audio/raw"
D/MediaCodec(21483):       int32_t channel-count = 2
D/MediaCodec(21483):       int32_t sample-rate = 44100
D/MediaCodec(21483):       int32_t pcm-encoding = 2
D/MediaCodec(21483):     }
I/MediaCodec(21483): name=OMX.qcom.video.decoder.avc isType=false encoder=false
I/MediaCodec(21483): (0x7f274200) init name(OMX.qcom.video.decoder.avc) isType(0) encoder(0)
I/OMXClient(21483): Treble IOmx obtained
I/MediaCodec(21483): (0x7f274200) Component Allocated (OMX.qcom.video.decoder.avc)
I/MediaCodec(21483): (0x7f274200) configure surface(0x87cee000) crypto(0x0) flags(0)
D/MediaCodec(21483): (0x7f274200) configure format: AMessage(what = 0x00000000) = {
D/MediaCodec(21483):       Buffer csd-1 = {
D/MediaCodec(21483):         00000000:  00 00 00 01 68 eb af 20                           ....h.. 
D/MediaCodec(21483):       }
D/MediaCodec(21483):       int32_t max-height = 720
D/MediaCodec(21483):       int32_t max-width = 1280
D/MediaCodec(21483):       string mime = "video/avc"
D/MediaCodec(21483):       int32_t width = 1280
D/MediaCodec(21483):       int32_t max-input-size = 26389
D/MediaCodec(21483):       int32_t rotation-degrees = 0
D/MediaCodec(21483):       int32_t height = 720
D/MediaCodec(21483):       Buffer csd-0 = {
D/MediaCodec(21483):         00000000:  00 00 00 01 67 4d 40 1f  e8 80 28 02 dd 80 b5 01  ....gM@...(.....
D/MediaCodec(21483):         00000010:  01 01 40 00 00 fa 40 00  2e e0 03 c6 0c 44 80     ..@[email protected].
D/MediaCodec(21483):       }
D/MediaCodec(21483):     }
D/SurfaceUtils(21483): connecting to surface 0x87cee008, reason connectToSurface
I/MediaCodec(21483): [OMX.qcom.video.decoder.avc] setting surface generation to 21998593
D/SurfaceUtils(21483): disconnecting from surface 0x87cee008, reason connectToSurface(reconnect)
D/SurfaceUtils(21483): connecting to surface 0x87cee008, reason connectToSurface(reconnect)
I/ACodec  (21483): DRC Mode: Dynamic Buffer Mode
I/ExtendedACodec(21483): setupVideoDecoder()
I/ACodec  (21483): [OMX.qcom.video.decoder.avc] setupVideoDecoder Width Height (1280x720)
I/ACodec  (21483): mime (video/avc) compressionFormat (7)
I/ExtendedACodec(21483): Decoder will be in frame by frame mode
I/MediaCodec(21483): (0x7f274200) start
D/SurfaceUtils(21483): set up nativeWindow 0x87cee008 for 1280x720, color 0x7fa30c04, rotation 0, usage 0x20002900
I/MediaCodec(21483): (0x7f274200) kWhatStartCompleted
W/GrallocMapperPassthrough(21483): buffer descriptor with invalid usage bits 0x2000
I/chatty  (21483): uid=10454(com.shinayser.tapthefab.app) CodecLooper identical 3 lines
W/GrallocMapperPassthrough(21483): buffer descriptor with invalid usage bits 0x2000
D/SurfaceUtils(21483): set up nativeWindow 0x87cee008 for 1280x720, color 0x7fa30c04, rotation 0, usage 0x20002900
D/MediaCodec(21483): (0x7f274200) kWhatOutputBuffersChanged
D/MediaCodec(21483): (0x7f274200) [OMX.qcom.video.decoder.avc] output format changed to: AMessage(what = 0x00000000) = {
D/MediaCodec(21483):       int32_t color-range = 2
D/MediaCodec(21483):       int32_t color-standard = 1
D/MediaCodec(21483):       int32_t color-transfer = 3
D/MediaCodec(21483):       string mime = "video/raw"
D/MediaCodec(21483):       int32_t stride = 1280
D/MediaCodec(21483):       int32_t slice-height = 736
D/MediaCodec(21483):       int32_t color-format = 2141391876
D/MediaCodec(21483):       Rect crop(0, 0, 1279, 719)
D/MediaCodec(21483):       int32_t android._dataspace = 260
D/MediaCodec(21483):       Buffer hdr-static-info = {
D/MediaCodec(21483):         00000000:  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
D/MediaCodec(21483):         00000010:  00 00 00 00 00 00 00 00  00                       .........
D/MediaCodec(21483):       }
D/MediaCodec(21483):       int32_t width = 1280
D/MediaCodec(21483):       int32_t height = 720
D/MediaCodec(21483):     }
D/AudioTrack(21483): Client defaulted notificationFrames to 4714 for frameCount 14144
W/AudioTrack(21483): Use of stream types is deprecated for operations other than volume control
W/AudioTrack(21483): See the documentation of AudioTrack() for what to use instead with android.media.AudioAttributes to qualify your playback use case
W/GrallocMapperPassthrough(21483): buffer descriptor with invalid usage bits 0x2000
I/DynamiteModule(21483): Considering local module com.google.android.gms.ads.dynamite:0 and remote module com.google.android.gms.ads.dynamite:22000
I/DynamiteModule(21483): Selected remote version of com.google.android.gms.ads.dynamite, version >= 22000
I/flutter (21483): GOT EVENT AdmobAdEvent.loaded com args: null

As you can see, the ads is being loaded up but not showing =( I am using admob_flutter: ^1.0.0-beta.7

shinayser avatar Sep 17 '20 23:09 shinayser

Maybe related to iOS 14, did you add the UsageDescription?

<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads to you.</string>

ming-chu avatar Sep 18 '20 06:09 ming-chu

Nope, it's Android!

shinayser avatar Sep 18 '20 13:09 shinayser

Nope, it's Android! @shinayser sorry about that.

I guess isLoaded is false here:

if (await rewardAd.isLoaded) {
    rewardAd.show();
}

I recommend you try to show the ad rewardAd.show(); in the listener instead of after check isLoaded immediately if you want to show after it loaded because the isLoaded computed variable seems not waiting for the ad finish it's fetching process.

class TestAds extends StatefulWidget {
  @override
  _TestAdsState createState() => _TestAdsState();
}

class _TestAdsState extends State<TestAds> {
  AdmobReward rewardAd;

  @override
  void initState() {
    rewardAd = AdmobReward(
      adUnitId: testRewardedId,
      listener: (event, args) {
        print('GOT EVENT $event com args: $args');
        if (event == AdmobAdEvent.loaded) {
          print('Ad Loaded!');
          rewardAd.show();
        }
      },
    );
    rewardAd.load();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

ming-chu avatar Sep 19 '20 12:09 ming-chu

@ming-chu Jsut tried your solution and nope, it also doesnt work =(

shinayser avatar Sep 19 '20 22:09 shinayser

@ming-chu Jsut tried your solution and nope, it also doesnt work =(

@shinayser Would you please post the code after you modified? Also, you may want to check the ad unit id used is for AdmobReward or not.

Ad format | Sample ad unit ID
Rewarded Video  | ca-app-pub-3940256099942544/5224354917

https://developers.google.com/admob/android/test-ads

ming-chu avatar Sep 20 '20 01:09 ming-chu

I'm also having the same problem. I've tried to use the test id from Google, but the ad is still not showing. I've changed the algorithm, it's still not showing.

Arie290698 avatar Sep 23 '20 10:09 Arie290698

I'm also having the same problem. I've tried to use the test id from Google, but the ad is still not showing. I've changed the algorithm, it's still not showing.

@Arie290698 Would you please provide the code that can reproduce the problem? That will be easier to check and discuss. :)

ming-chu avatar Sep 23 '20 15:09 ming-chu

Sorry for the late response. Here it goes:

Future<int> _showRewardedAlt() async {
  var completer = Completer<int>();

  AdmobReward rewardAd;
  rewardAd = AdmobReward(
    adUnitId: 'ca-app-pub-3940256099942544/5224354917',
    listener: (event, args) {
      print('EVENT ARGS $args');
      switch (event) {
        case AdmobAdEvent.rewarded:          
            completer.complete(args["rewardAmount"]);          
          break;

        case AdmobAdEvent.clicked:
        case AdmobAdEvent.impression:
        case AdmobAdEvent.opened:
        case AdmobAdEvent.started:
        case AdmobAdEvent.completed:
          print('New reward event: $event');
          break;

        case AdmobAdEvent.failedToLoad:
        case AdmobAdEvent.leftApplication:
        case AdmobAdEvent.closed:
          print('Rewarded event ERROR with $event');
          completer.completeError(event);
          break;

        case AdmobAdEvent.loaded:
          print('LOADED');
          rewardAd.show();
          break;
      }
    },
  );

  rewardAd.load();

  return completer.future;
}

shinayser avatar Sep 23 '20 15:09 shinayser

Sorry for the late response. Here it goes:

Future<int> _showRewardedAlt() async {
  var completer = Completer<int>();

  AdmobReward rewardAd;
  rewardAd = AdmobReward(
    adUnitId: 'ca-app-pub-3940256099942544/5224354917',
    listener: (event, args) {
      print('EVENT ARGS $args');
      switch (event) {
        case AdmobAdEvent.rewarded:          
            completer.complete(args["rewardAmount"]);          
          break;

        case AdmobAdEvent.clicked:
        case AdmobAdEvent.impression:
        case AdmobAdEvent.opened:
        case AdmobAdEvent.started:
        case AdmobAdEvent.completed:
          print('New reward event: $event');
          break;

        case AdmobAdEvent.failedToLoad:
        case AdmobAdEvent.leftApplication:
        case AdmobAdEvent.closed:
          print('Rewarded event ERROR with $event');
          completer.completeError(event);
          break;

        case AdmobAdEvent.loaded:
          print('CARREGOU');
          rewardAd.show();
          break;
      }
    },
  );

  rewardAd.load();

  return completer.future;
}

@shinayser I guess the instance of AdmobReward does not exist after the function is finished before the ad loaded. you should define the variable AdmobReward rewardAd; outside the function

ming-chu avatar Sep 23 '20 16:09 ming-chu

@shinayser I tried using a new project with the code below and it works. pubspec.yaml: admob_flutter: ^1.0.0-beta.7

import 'package:admob_flutter/admob_flutter.dart';
import 'package:flutter/material.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  Admob.initialize();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  AdmobReward rewardAd;

  @override
  void initState() {
    rewardAd = AdmobReward(
      adUnitId: 'ca-app-pub-3940256099942544/5224354917',
      listener: (event, args) {
        print('GOT EVENT $event, args: $args');
        if (event == AdmobAdEvent.loaded) {
          print('Ad Loaded!');
          rewardAd.show();
        } else if (event == AdmobAdEvent.closed) {
          rewardAd.load();
        }
      },
    );
    rewardAd.load();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Demo the AdmobReward'),
            RaisedButton(
              child: Text('Show Ad!'),
              onPressed: () {
                print('Show ad by clicking button!');
                rewardAd.isLoaded.then((isLoaded) {
                  print('isLoaded: $isLoaded');
                  if (isLoaded) {
                    rewardAd.show();
                  }
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}

ming-chu avatar Sep 23 '20 16:09 ming-chu

@shinayser I guess the instance of AdmobReward does not exist after the function is finished before the ad loaded. you should define the variable AdmobReward rewardAd; outside the function

This is not true. The variable exists, otherwise it would throw a null pointer exception. The purpose of my function is to provide a streaightfoward way to show and ad and get its result in a single call.

shinayser avatar Sep 23 '20 16:09 shinayser

@shinayser I tried your code, but the listener of AdmobReward never called. What I guess is the instant was destroyed before the listener is called.

ming-chu avatar Sep 23 '20 16:09 ming-chu

@ming-chu There isn't much difference from the code you posted. You doign almost the same thing as I, except that I am doing it via future Completer. Perhaps it is another bug on the library?

shinayser avatar Sep 23 '20 16:09 shinayser

@shinayser I guess the instance of AdmobReward does not exist after the function is finished before the ad loaded. you should define the variable AdmobReward rewardAd; outside the function

This is not true. The variable exists, otherwise it would throw a null pointer exception. The purpose of my function is to provide a streaightfoward way to show and ad and get its result in a single call.

@shinayser You are right!

After some tests, I suspect that is the problem at the listener, I move the listener out and it works. please try the code below.

  Future<int> _showRewardedAlt() async {
    var completer = Completer<int>();

    AdmobReward rewardAd;

    void listener(AdmobAdEvent event, Map<String, dynamic> args) {
      print('>>>>EVENT ARGS $args');
      switch (event) {
        case AdmobAdEvent.rewarded:
          completer.complete(args["rewardAmount"]);
          break;

        case AdmobAdEvent.clicked:
        case AdmobAdEvent.impression:
        case AdmobAdEvent.opened:
        case AdmobAdEvent.started:
        case AdmobAdEvent.completed:
          print('New reward event: $event');
          break;

        case AdmobAdEvent.failedToLoad:
        case AdmobAdEvent.leftApplication:
        case AdmobAdEvent.closed:
          print('Rewarded event ERROR with $event');
          completer.completeError(event);
          break;

        case AdmobAdEvent.loaded:
          print('CARREGOU');
          rewardAd.show();
          break;
      }
    }

    rewardAd = AdmobReward(
      adUnitId: 'ca-app-pub-3940256099942544/5224354917',
      listener: listener,
    );

    rewardAd.load();
    return completer.future;
  }

ming-chu avatar Sep 23 '20 17:09 ming-chu

void listener(AdmobAdEvent event, Map<String, dynamic> args) {

I tried exactly your code and my rewarded ads don't show up =(

shinayser avatar Sep 23 '20 17:09 shinayser

@Arie290698 Would you please provide the code that can reproduce the problem? That will be easier to check and discuss. :)

It's okay. I've solved the problem.

Arie290698 avatar Sep 23 '20 17:09 Arie290698

@shinayser That's so weird, I try to use your original code and it works too. What I did is just stop the app and start, don't use hot reload / hot restart. Hope this can help.

ming-chu avatar Sep 23 '20 17:09 ming-chu

@Arie290698 Would you please provide the code that can reproduce the problem? That will be easier to check and discuss. :)

It's okay. I've solved the problem.

Can you share your solution?

shinayser avatar Sep 23 '20 17:09 shinayser

@shinayser Add this to initState ()

rewardAd = AdmobReward (
       adUnitId: rewardId,
       listener: (AdmobAdEvent event, Map <String, dynamic> args) {
         if (event == AdmobAdEvent.rewarded) {
           rewardAd.load ();
         }
         if (event == AdmobAdEvent.closed) {
           rewardAd.load ();
         }
       },
     );
loadReward();

Then add a new function loadReward()

loadReward() async{
    if(await rewardAd.isLoaded == false){
      rewardAd.load();
    }
  }

Then add this code to onClick on the button as the trigger

if(await rewardAd.isLoaded == true){
      rewardAd.show();
}else{
//do something if reward not loaded
}

Run flutter clean and try rebuilding your app

Arie290698 avatar Sep 23 '20 18:09 Arie290698

If it's still not loading, try using your app's app_id and unit_id. But don't forget to add Admob.initialize (testDeviceIds: ['test_device']); Because when I try to use Google's app_id and unit_id, the ad doesn't show.

Arie290698 avatar Sep 23 '20 18:09 Arie290698

@shinayser This is my little testing app, it works with your code perfectly. demo2

https://github.com/ming-chu/admob-flutter-reward-test https://github.com/ming-chu/admob-flutter-reward-test/blob/master/lib/main.dart

ming-chu avatar Sep 23 '20 18:09 ming-chu

I also faced this problem too. Listener is not firing and ad is not showing.

mehmetyilmaz001 avatar Nov 08 '20 14:11 mehmetyilmaz001

Don't use admob_flutter. Just use firebase_admob, and it is reliable.

it-one-mm avatar Jan 11 '21 13:01 it-one-mm

The listener function was not being called,

  • I stopped the debug session.
  • run: flutter clean
  • Run debug again, and it works.

  static Future<bool> showRewardVideo({String adType = 'Reward'}) {
    Completer<bool> completer = Completer<bool>();

    var rewarded = false;

    rewardAd = AdmobReward(
      adUnitId: getRewardBasedVideoAdUnitId(),
      listener: (AdmobAdEvent event, Map<String, dynamic> args) {
        if (event == AdmobAdEvent.closed) {}
        switch (event) {
          case AdmobAdEvent.loaded:
            print('New Admob $adType Ad loaded!');
            rewardAd.show();

            break;
          case AdmobAdEvent.opened:
            print('Admob $adType Ad opened!');
            break;
          case AdmobAdEvent.closed:
            print('Admob $adType Ad closed!');
            if (rewarded) {
              completer.complete(true);
            } else {
              completer.complete(false);
            }
            rewardAd.dispose();
            break;
          case AdmobAdEvent.failedToLoad:
            print('Admob $adType failed to load. :(');
            completer.completeError(false);
            rewardAd.dispose();
            break;
          case AdmobAdEvent.rewarded:
            print('!!!!rewarded');
            rewarded = true;
            break;
          default:
        }
      },
    );

    rewardAd.load();

    return completer.future;
  }


    AdsHelper.showRewardVideo().then((value)  {
      if (!value) {
        // no reward
        return;
      }

      //Rewarded... 
    }).catchError((error) {
      //error loading or showing video
    });

for purpose of the test, use AdmobReward.testAdUnitId to make sure it is not an AdMob setup issue.

doonfrs avatar Jan 26 '21 20:01 doonfrs

where can I call this function? onPress or initState method?

amirVirtuenetz avatar Oct 18 '22 12:10 amirVirtuenetz