Watch And Earn docs
v3.0.0
Live demoConsole demo Get help
● Set up · Ad networks

Ads
one build, four networks.

Choose AdMob, AppLovin MAX, Unity Ads or ironSource LevelPlay in the console, enter the ids, and point the network's reward callback to your Cloud Function. Points for a video are credited only by that callback.

AdMobAppLovin MAXUnity AdsironSource LevelPlay

01How a rewarded video is credited

  1. The app asks for a sessionIt calls requestAdSession, which checks the daily cap and the cooldown and returns a one-time nonce.
  2. The app shows the videoIt passes the user id and the nonce to the ad SDK (app/lib/ads/native_adapters.dart).
  3. The ad network calls your functionAfter the user watched, the network's server calls ssvAdmob, ssvApplovin, ssvUnity or ssvIronsource.
  4. The function verifies and credits onceIt checks the network's signature (a bad signature gets 403), removes duplicates, matches the pending session of the same user and credits the points in one transaction. A mismatch opens a fraud flag that you review in the console.
No callback, no points

The app never credits itself. If the callback URL is missing or wrong in the network's dashboard, users watch videos and receive nothing. Set up the callback before you release.

02Choose the network

In the console open Ads and pick the Ad network. The default is AdMob. The app reads the choice from config/public, so switching needs no new build. All four SDKs are inside every build.

Setting (console → Ads)DefaultMeaning
Ad networkAdMobThe network for rewarded, interstitial and banner ads.
Interstitial every n-th screen change00 = no interstitials.
Seconds between interstitials (minimum)120Minimum gap between two interstitials (30 to 3600).
Banner on the home screenoffShows a banner on the home screen.

Users who bought remove-ads, and users with an active VIP subscription, see no interstitials and no banners (showsAds in app/lib/data/models.dart). Rewarded videos stay available because the user chooses them.

03Ids and keys per network

Each network has its own section in the console (AdMob units, AppLovin MAX units, Unity Ads units, ironSource LevelPlay units). The Status page warns when the chosen network lacks its required ids or its verification secret.

NetworkRequired idsAlso availableVerification secret
AdMobAndroid rewarded unit, iOS rewarded unitInterstitial and banner units per platformNone. Verified with Google's public keys.
AppLovin MAXSDK key, Android and iOS rewarded unitsInterstitial and banner unitsAppLovin S2S event key: MAX dashboard → Account → General → Keys → Event Key
Unity AdsAndroid and iOS game ids, Android and iOS rewarded units (placement ids)Interstitial and banner unitsUnity S2S secret: sent to you by Unity Ads support when you register the callback URL
ironSource LevelPlayAndroid and iOS app keys, Android and iOS rewarded unitsInterstitial and banner unitsironSource private key: LevelPlay → Settings → Server-to-server callback → Private Key (you choose it)

Secrets are write-only in the console, only an owner can change them, and they are stored encrypted with ADMIN_SECRET_KEY. The console writes them to config/private, which only Cloud Functions can read.

04Server-to-server callback URLs

Replace REGION-PROJECT with your region and project id, for example us-central1-my-project. The exact URLs are printed by firebase deploy and shown in Firebase console → Functions. Set the console's Backend → Cloud Functions base URL to https://REGION-PROJECT.cloudfunctions.net as well.

AdMob

Where: AdMob → Apps → Ad units → your rewarded unit → Server-side verification.

https://REGION-PROJECT.cloudfunctions.net/ssvAdmob

AppLovin MAX

Where: MAX → Manage → Ad Units → your rewarded unit → S2S Rewarded Callback URL.

https://REGION-PROJECT.cloudfunctions.net/ssvApplovin?user_id={USER_ID}&custom_data={CUSTOM_DATA}&event_id={EVENT_ID}&event_token={EVENT_TOKEN}&amount={AMOUNT}&currency={CURRENCY}&ad_unit={AD_UNIT_ID}&ts={TS}

Unity Ads

Where: e-mail Unity Ads support with your Game IDs and this URL. They reply with the secret; enter it as Unity S2S secret.

https://REGION-PROJECT.cloudfunctions.net/ssvUnity

ironSource LevelPlay

Where: LevelPlay → Settings → Server-to-server callback → Callback URL. Enable it for Rewarded, and set the Private Key you also enter in the console.

https://REGION-PROJECT.cloudfunctions.net/ssvIronsource
Test one real LevelPlay callback

The app passes the nonce with setDynamicUserId. The parameter name dynamicUserId comes from the ironSource SDK guides; the function also accepts custom_nonce as a fallback. After setup, trigger one real callback from the LevelPlay dashboard and confirm the user receives points.

How each callback is checked

NetworkCheck (firebase/functions/src/ssv/)
AdMobECDSA signature over the query string, Google's verifier keys (cached up to 6 hours). user_id = uid, custom_data = nonce.
AppLovin MAXevent_token must equal sha1(event_id + Event Key).
Unity Adshmac = HMAC-MD5(secret, other parameters sorted). sid = uid:nonce. Answers 1.
ironSource LevelPlaysignature = md5(timestamp + eventId + applicationUserId + rewards + private key). Answers <eventId>:OK.

05Test ids ship by default

The package contains only Google's public AdMob test ids; a test enforces it. With AdMob selected and no unit ids entered, the app falls back to Google's test units (app/lib/ads/ad_adapter.dart), so you see test ads during development. They never earn anything. The other three networks show nothing until their ids are entered.

06Replace the AdMob test app ids

Required before release

The Google Mobile Ads plugin needs an AdMob app id inside the app itself. The package ships Google's test app ids:

FileKeyShipped test value
app/android/app/src/main/AndroidManifest.xmlcom.google.android.gms.ads.APPLICATION_IDca-app-pub-3940256099942544~3347511713
app/ios/Runner/Info.plistGADApplicationIdentifierca-app-pub-3940256099942544~1458002511

Replace both with your own app ids from AdMob → Apps → App settings (one Android app, one iOS app).

Tests stay green

app/test/no_cash_out_test.dart checks only the Dart code for AdMob ids, so putting your own app id in AndroidManifest.xml and Info.plist does not break flutter test. Enter your unit ids in the operator console, not in the code.

The Google plugin is in every build and also provides the consent form below, so keep a valid AdMob app id even if you serve ads from another network.

If you use another network on iOS, also add that network's SKAdNetworkItems entries to Info.plist as its integration guide describes. The package lists Google's entry only.

08Check it worked

  • Console → Status shows no warning for "Ad unit ids set for the chosen network" and "Rewarded-ad verification secret set"
  • Watch one video on a real device: the balance goes up within seconds and the console Ledger shows an ad row
  • No new rows in Fraud flags for your own test views