Watch And Earn docs
v4.0.0
Live demoConsole demo Get help
● Ship · Stores

Release build
sign, build, publish.

The pre-release checklist, Android signing, the build commands for Google Play and the App Store, and the optional web demo.

01Before the first release

  • Your own Firebase project, deployed, with flutterfire configure done (Firebase setup)
  • Your own application id and bundle id (Rebranding)
  • Your own AdMob app ids in AndroidManifest.xml and Info.plist (Ads)
  • Ad network unit ids and the verification secret in the console for every network you use; the callback URL set in each network; one real video credited
  • Only the ad placements you want switched on, with their caps (Placements)
  • Each enabled offerwall or survey: one test postback credited (testing)
  • If the cash wallet is on: the app renamed from the default "Watch And Earn" (why); legal review done, payout terms published, one payout tested end to end, payout accounts funded, iOS left off unless you checked Apple's rules (Switching the wallet on)
  • iOS: CFBundleLocalizations still lists every language you ship (all 9 out of the box; Languages)
  • UMP consent messages published in AdMob → Privacy & messaging
  • App Check registered and enforced; ENFORCE_APP_CHECK is true
  • Privacy policy, terms and rewards rules URLs in console → Legal; Status page without warnings
  • Android release signing set up (below)
  • If you build with a non-default region: --dart-define=FUNCTIONS_REGION=… on every build

02Version number

app/pubspec.yaml has version: 4.0.0+400: 4.0.0 is the version users see, 400 the build number. Raise the build number for every upload; both stores refuse a number they have already seen.

03Android signing

The package signs release builds with the debug key so flutter run --release works out of the box (app/android/app/build.gradle.kts, buildTypes.release). Google Play refuses debug-signed apps, so create your own upload key.

  1. Create the keyKeep the file and the passwords safe and outside git. Losing them means you cannot update the app without Google's help.
    keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
  2. Create app/android/key.properties
    storePassword=<password>
    keyPassword=<password>
    keyAlias=upload
    storeFile=<absolute path to upload-keystore.jks>
  3. Use it in app/android/app/build.gradle.ktsFollow Flutter's "Build and release an Android app" guide (Kotlin DSL): load key.properties, add a signingConfigs { create("release") { … } } block and set signingConfig = signingConfigs.getByName("release") in buildTypes.release instead of the debug one.
  4. Fingerprints to FirebaseAdd the SHA-1 and SHA-256 of your upload key, and of the app signing key shown in Play Console → Setup → App signing, in Firebase Project settings. Google sign-in and Play Integrity need them.

04Build for Google Play

cd app
flutter build appbundle   # add --dart-define=FUNCTIONS_REGION=... if not us-central1

Upload app/build/app/outputs/bundle/release/app-release.aab to Play Console, first to Internal testing. Test sign-in, a rewarded video, the wheel, a quiz and account deletion on the internal build before you promote it.

05Build for the App Store

  1. SigningOpen app/ios/Runner.xcworkspace in Xcode → Runner → Signing & Capabilities. Choose your team. Add Sign in with Apple, Push Notifications, Background Modes → Remote notifications and In-App Purchase. Minimum Deployments is already 15.0.
  2. Build
    cd app
    flutter build ipa
  3. UploadUpload app/build/ios/ipa/*.ipa with Apple's Transporter app or from Xcode's Organizer, then test through TestFlight.

06Rename the app before the cash wallet goes on

"Watch And Earn" is only the default label

The package ships with the name "Watch And Earn" in console → Brand (Product name), android:label in app/android/app/src/main/AndroidManifest.xml, CFBundleDisplayName and CFBundleName in app/ios/Runner/Info.plist, and the web <title> and manifest.json. Next to a cash wallet, that name reads like "watch ads, earn money", which is exactly what AdMob's rewards policy and the stores' deceptive-behaviour rules forbid. Before you switch the cash wallet on, give the app your own name, icon and store listing (Rebranding).

  • Never market the app, in its name, icon, screenshots, store text or ads, as a way to earn money by watching ads, playing games or collecting points.
  • Describe cash truthfully: rewards from completed partner offers and surveys, with a minimum, a hold and an approval step.
  • Keep the in-app wallet notice and "How cash works" consistent with that (Platform rules).

07Store listing

  • Never promise income, and never suggest that watching ads, playing games or collecting points pays money. With the wallet off, describe a rewards app with points and badges. With the wallet on, say that cash rewards come from completed partner offers and surveys, with a minimum, a hold and an approval step (Google Play).
  • Answer the content rating questionnaire, the Data safety form (Play) and the App Privacy section (Apple) truthfully.
  • Give reviewers a way in: guest sign-in works without an account.

See Policy and compliance.

08Optional: host the web demo

The web target is meant for demo mode (simulated ads, in-memory backend): the ad SDKs and store purchases do not run on the web. It is useful as a public preview, not as the product.

cd app
flutter build web --dart-define=DEMO_MODE=true   # output in app/build/web, any static host

09The console in production

Run it over HTTPS, keep ADMIN_SECRET_KEY and the data/ folder (or your Postgres) backed up, and give team members the lowest role they need. See Deploy options.