I'm attempting to understand why I'm receiving the 'No Ads Found' error message.
Native ads from the Facebook Audience Network (FAN) to show within the Android RecyclerView feed the same way the test ad units show in the screenshot below.
I have followed the Android setup for native ads. The app is not live on the Play Store as it is still in testing.
AndroidManifest.xml
...
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="[app-package-here]">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@drawable/logo"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity android:name="[app-package-here].MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.mopub.common.privacy.ConsentDialogActivity" android:configChanges="keyboardHidden|orientation|screenSize"/>
<activity android:name="com.mopub.common.MoPubBrowser" android:configChanges="keyboardHidden|orientation|screenSize"/>
</application>
</manifest>
network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system"/>
</trust-anchors>
</base-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">127.0.0.1</domain>
<domain includeSubdomains="true">example.com</domain>
<domain includeSubdomains="true">cdn.example2.com</domain>
</domain-config>
</network-security-config>
build.gradle (Module)
implementation('com.mopub:mopub-sdk-native-static:5.4.1@aar') {
transitive = true
}
implementation 'com.facebook.android:audience-network-sdk:5.1.0'
implementation 'com.mopub.mediation:facebookaudiencenetwork:5.1.0.0'
build.gradle (App)
buildscript {
ext.kotlin_version = '1.3.11'
repositories {
google()
jcenter()
mavenCentral()
maven { url 'https://maven.google.com' }
maven { url "https://s3.amazonaws.com/moat-sdk-builds" }
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.gms:google-services:4.2.0'
classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0-alpha09"
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://s3.amazonaws.com/moat-sdk-builds" }
}
}
MainActivity
val sdkConfiguration = SdkConfiguration.Builder([ad-unit-id-here])
.build()
MoPub.initializeSdk(this, sdkConfiguration, initSdkListener())
Activity/Fragment
private fun populateAdapterType() {
moPubAdapter = MoPubRecyclerAdapter(activity!!, adapter,
MoPubNativeAdPositioning.MoPubServerPositioning())
val moPubStaticNativeAdRenderer = MoPubStaticNativeAdRenderer(
ViewBinder.Builder(R.layout.native_ad_list_item)
.titleId(R.id.native_title)
.textId(R.id.native_text)
.mainImageId(R.id.native_main_image)
.iconImageId(R.id.native_icon_image)
.callToActionId(R.id.native_cta)
.privacyInformationIconImageId(R.id.native_privacy_information_icon_image)
.build()
)
moPubAdapter.registerAdRenderer(moPubStaticNativeAdRenderer)
contentRecyclerView.adapter = moPubAdapter
moPubAdapter.loadAds([ad-unit-id-here])
}
App
Ad Unit
Network
Segment
The test ad unit id 11a17b188668469fb0412708c3d16813 is showing successfully. However, live Facebook ads are not shown when using the ad unit id created in the MoPub console.
Error: "MoPubNetworkError: No ads found for ad unit"
Full Error
2019-01-11 18:46:12.312 29624-29624/[app-package-here] D/MoPub: MoPubNative Loading ad from: https://ads.mopub.com/m/ad?id=[ad-id-here]&nv=5.4.1&dn=Google%2CPixel%202%2Cwalleye&bundle=[app-package-here]&z=-0800&o=p&w=1080&h=1920&sc=2.625&mcc=310&mnc=260&cn=Google%20Fi&ct=2&av=0.15&udid=mp_tmpl_advertising_id&dnt=mp_tmpl_do_not_track&gdpr_applies=0&force_gdpr_applies=0¤t_consent_status=unknown&MAGIC_NO=0
2019-01-11 18:46:12.689 29624-29624/[app-package-here] D/MoPub: Attempting to invoke custom event: com.mopub.nativeads.FacebookNative
2019-01-11 18:46:13.114 29624-29624/[app-package-here] D/MoPub: Successfully hit tracking endpoint: https://ads.mopub.com/m/attempt
2019-01-11 18:46:13.205 29624-29624/[app-package-here] W/MoPub: MoPubNative.onNativeAdLoaded com.mopub.nativeads.CustomEventNativeAdapter@708f83c
2019-01-11 18:46:13.206 29624-29624/[app-package-here] V/MoPub: Native Ad failed to load with error: A required renderer was not registered for the CustomEventNative..
2019-01-11 18:46:13.394 29624-29624/[app-package-here] D/MoPub: Native ad request failed.
com.mopub.network.MoPubNetworkError: No ads found for ad unit.
at com.mopub.network.MultiAdResponse.(MultiAdResponse.java:157)
at com.mopub.network.MultiAdRequest.parseNetworkResponse(MultiAdRequest.java:96)
at com.mopub.volley.NetworkDispatcher.processRequest(NetworkDispatcher.java:132)
at com.mopub.volley.NetworkDispatcher.run(NetworkDispatcher.java:87)
With the correct placement ID the Facebook Ad Request Debugger is showing requests being made by MoPub.
Facebook Monetization Manager
MoPub Network Settings > App and ad unit setup
Facebook Ad Request Debugger
I've also added a test device with my phone's AAID per Facebook's testing documentation so not being live on the Play Store should not be an issue.
Under MoPub's Integrating 3rd Party Ad Networks it explains that a unique Ad Renderer is required for Facebook in addition to using a specific Facebook layout.
FacebookAdRenderer facebookAdRenderer = new FacebookAdRenderer( new FacebookAdRenderer.FacebookViewBinder.Builder(R.layout.native_ad_list_item) .titleId(R.id.native_title) .textId(R.id.native_text) // Binding to new layouts from Facebook 4.99.0+ .mediaViewId(R.id.native_main_image) .adIconViewId(R.id.native_icon_image) .adChoicesRelativeLayoutId(R.id.native_ad_choices_relative_layout) .advertiserNameId(R.id.native_title) // Bind either the titleId or advertiserNameId depending on the FB SDK version // End of binding to new layouts .callToActionId(R.id.native_cta) .build());
To know which specific layout elements to use in your XML for the MediaView, AdIconView, and AdChoices RelativeLayout in the FacebookViewBinder, please reference this sample XML layout. Additionally, depending on the Facebook SDK version you are integrating, you will need to show only either the ad title or the advertiser name. For more information about Facebook’s implementation requriements, check out this article.
Then, register your ad renderers, like below. Your classThatRegistersAdRenderers varies depending on which native ad integration you are using. Remember to register your MoPubStaticNativeAdRenderer instance last.
// MoPubRecyclerAdapter MoPubRecyclerAdapter classThatRegistersAdRenderers = new MoPubRecyclerAdapter(...); // MoPubStreamAdPlacer MoPubStreamAdPlacer classThatRegistersAdRenderers = new MoPubStreamAdPlacer(...); // MoPubAdAdapter MoPubAdAdapter classThatRegistersAdRenderers = new MoPubAdAdapter(...); // MoPubNative MoPubNative classThatRegistersAdRenderers = new MoPubNative(...); classThatRegistersAdRenderers.registerAdRenderer( googlePlayServicesAdRenderer); classThatRegistersAdRenderers.registerAdRenderer( flurryNativeAdRenderer); classThatRegistersAdRenderers.registerAdRenderer(facebookAdRenderer); classThatRegistersAdRenderers.registerAdRenderer(staticAdRender);