Search code examples
androidadmobnative-ads

google loads native ad banner only once


I'm implementing google native ads on android.Most of the code I copy/pasted from this example The only difference is I request bunch of ads instead of one ad.Here is load function:

  public void loadAds(String unitId,int count) {
        if (nativeAds.size()>0) {
            for(UnifiedNativeAd ad: nativeAds)
                ad.destroy();
        }
        nativeAds =new ArrayList();
        //load
        AdLoader.Builder builder = new AdLoader.Builder(context, unitId);

        builder.forUnifiedNativeAd(new UnifiedNativeAd.OnUnifiedNativeAdLoadedListener() {
            // OnUnifiedNativeAdLoadedListener implementation.
            @Override
            public void onUnifiedNativeAdLoaded(UnifiedNativeAd nativeAd) {
                // You must call destroy on old ads when you are done with them,
                // otherwise you will have a memory leak.
                //nativeAd = unifiedNativeAd;
                int numAds =nativeAds.size();
                int insertTo=numAds==0? firstAdPosition : firstAdPosition +numAds*(AdStep +1);
                CategoryData item = new CategoryData();
                item.type = ItemData.TYPE_CATEGORIES_NATIVE_AD;
                if (insertTo<data.size())
                    data.add(insertTo, item);

                item = new CategoryData();
                item.type = ItemData.TYPE_CATEGORIES_SEPARATOR;
                if (insertTo<data.size())
                data.add(insertTo+1, item);

                nativeAds.add(nativeAd);
                Log.d("nativead","got ad body "+nativeAds.size()+":"+nativeAd.getBody());
                notifyItemRangeInserted(insertTo,2);
            }

        });

        VideoOptions videoOptions = new VideoOptions.Builder()
                .setStartMuted(true)
                .build();

        NativeAdOptions adOptions = new NativeAdOptions.Builder()
                .setVideoOptions(videoOptions)
                .build();

        builder.withNativeAdOptions(adOptions);

        AdLoader adLoader = builder.withAdListener(new AdListener() {
            @Override
            public void onAdFailedToLoad(int errorCode) {
                Log.d("nativead","error code " +errorCode);
                /*
                Toast.makeText(context, "Failed to load native ad: "
                        + errorCode, Toast.LENGTH_SHORT).show();
                 */
            }
        }).build();
        AdRequest adRequest;
       // get unpersonalized ads if needed
        if(AppModel.getAppData().gdpr.eea && AppModel.getAppData().gdpr.consentStatus!= ConsentStatus.PERSONALIZED) {
            Bundle extras = new Bundle();
            extras.putString("npa", "1");
            adRequest = new AdRequest.Builder().addNetworkExtrasBundle(AdMobAdapter.class,extras).build();
        } else {
            adRequest = new AdRequest.Builder().build();
        }
        adLoader.loadAds(adRequest,count);
        //adLoader.loadAd(adRequest);
    }

First time it loads ok, but if I restart the app it throws a bunch of errors:

I/Ads: Received log message: The ad request returned a no fill for the particular slot. The error log below that says 'Malformed native JSON response' is a benign warning that will be removed in a future SDK release.

Also error code 0 is passed into onAdFailedToLoad.If I clear app's data banners are loaded again but again only for single run


Solution

  • As you mentioned, in the comment above, you're testing it on real ad units (which is quite dangerous as you might get blocked for that).

    You're getting NO_FILL, which means there is no inventory left to serve in the AdMob backend.

    You can find out more about this issue (not an issue, we can call it a "thing") here.

    To get proper results, always test with test ads, so that you get maximum fill rate for the ads while testing.

    You'll find the ad unit ID's for test ads on this page.

    And, if you still get NO_FILL error a lot in production, try using mediation to get ads from multiple ad sources. You'll never get 100% fill rate for your ads, though, so make sure you code accordingly to handle the NO_FILL.

    Also, one more reminder, do not use live ads to test the app, you might get blocked by Admob/Google for doing that.