JustBaat Ads Flutter Plugin - Production Implementation Guide

Overview

This guide will help you integrate the JustBaat Ads Flutter plugin into your production Flutter application. The plugin provides a Flutter-compatible wrapper for the JustBaat Ads SDK, enabling you to display ads from Google AdMob and Unity Ads networks.

Quick Start - Production Setup

For production apps, use the Maven repository setup:

  1. Add Maven repository in settings.gradle or settings.gradle.kts:

    dependencyResolutionManagement {
        repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
        repositories {
            google()
            mavenCentral()
            maven { url = uri("https://justbaat-apps-b325d.web.app") }
        }
    }
    
  2. Add SDK dependencies in app/build.gradle (Next-Gen SDK):

    dependencies {
        implementation("com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:1.2.1")
        implementation("com.justbaatAds:adsSdk:1.1.1")
        implementation("com.google.android.material:material:1.12.0")
        implementation("com.google.code.gson:gson:2.10.1")
        implementation("com.unity3d.ads-mediation:mediation-sdk:8.9.1")
        implementation("com.google.android.gms:play-services-appset:16.0.0")
        implementation("com.google.android.gms:play-services-ads-identifier:18.1.0")
        implementation("com.google.android.gms:play-services-basement:18.1.0")
    }
    
  3. Add plugin to pubspec.yaml:

    dependencies:
      justbaat_ads: ^1.1.1
    # Until 1.1.1 is on pub.dev, use a local/git override instead:
    # dependency_overrides:
    #   justbaat_ads:
    #     path: ../flutter_plugin
    
  4. Initialize SDK in your Flutter app (see Step 3 below)


Prerequisites

  • Flutter SDK: >=3.0.0
  • Android: minSdk 24, compileSdk 35
  • Android Gradle Plugin: 8.6.0+
  • Kotlin: 2.1.0+
  • JustBaat Ads SDK: Version 1.1.1 (Next-Gen; available via Maven repository)
  • Uses the Google Mobile Ads Next-Gen SDK (ads-mobile-sdk) — do not add the legacy play-services-ads

Step 1: Add Plugin to Your Flutter Project

1.1 Update pubspec.yaml

Add the plugin as a dependency:

dependencies:
  flutter:
    sdk: flutter
  justbaat_ads: ^1.1.1

Note: 1.1.1 (Next-Gen) must be published to pub.dev to resolve. Until then, keep ^1.0.4 and add a local/git override:

dependency_overrides:
  justbaat_ads:
    path: ../flutter_plugin   # or git: { url: <plugin repo> }

1.2 Install Dependencies

flutter pub get

Step 2: Configure Android Project

2.1 Update android/settings.gradle (or settings.gradle.kts)

For Production (Using Maven Repository):

If using Groovy (settings.gradle):

pluginManagement {
    def flutterSdkPath = {
        def properties = new Properties()
        file("local.properties").withInputStream { properties.load(it) }
        def flutterSdkPath = properties.getProperty("flutter.sdk")
        assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
        return flutterSdkPath
    }()

    includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    id "dev.flutter.flutter-plugin-loader" version "1.0.0"
    id "com.android.application" version "8.6.0" apply false
    id "com.android.library" version "8.6.0" apply false
    id "org.jetbrains.kotlin.android" version "2.1.0" apply false
    id "org.jetbrains.kotlin.plugin.compose" version "2.1.0" apply false
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://justbaat-apps-b325d.web.app") }
    }
}

include ":app"

// Note: Flutter plugin is auto-discovered, no need to include it manually
// SDK is fetched from Maven repository, not included as a project module

If using Kotlin DSL (settings.gradle.kts):

pluginManagement {
    val flutterSdkPath: String = run {
        val properties = java.util.Properties()
        file("local.properties").inputStream().use { properties.load(it) }
        val flutterSdkPath = properties.getProperty("flutter.sdk")
            ?: throw GradleException("flutter.sdk not set in local.properties")
        flutterSdkPath
    }

    includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")

    repositories {
        google()
        mavenCentral()
        gradlePluginPortal()
    }
}

plugins {
    id("dev.flutter.flutter-plugin-loader") version "1.0.0" apply false
    id("com.android.application") version "8.6.0" apply false
    id("com.android.library") version "8.6.0" apply false
    id("org.jetbrains.kotlin.android") version "2.1.0" apply false
    id("org.jetbrains.kotlin.plugin.compose") version "2.1.0" apply false
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://justbaat-apps-b325d.web.app") }
    }
}

include(":app")

2.2 Update android/app/build.gradle (or build.gradle.kts)

For Production (Using Maven Repository):

Set minSdk = 24 in defaultConfig (required by the Next-Gen SDK), then add:

If using Groovy (build.gradle):

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.1.0"
    implementation "com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:1.2.1"
    implementation "com.justbaatAds:adsSdk:1.1.1"
    implementation "com.google.android.material:material:1.12.0"
    implementation "com.google.code.gson:gson:2.10.1"
    implementation "com.unity3d.ads-mediation:mediation-sdk:8.9.1"
    implementation "com.google.android.gms:play-services-appset:16.0.0"
    implementation "com.google.android.gms:play-services-ads-identifier:18.1.0"
    implementation "com.google.android.gms:play-services-basement:18.1.0"
}

If using Kotlin DSL (build.gradle.kts):

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.1.0")
    implementation("com.google.android.libraries.ads.mobile.sdk:ads-mobile-sdk:1.2.1")
    implementation("com.justbaatAds:adsSdk:1.1.1")
    implementation("com.google.android.material:material:1.12.0")
    implementation("com.google.code.gson:gson:2.10.1")
    implementation("com.unity3d.ads-mediation:mediation-sdk:8.9.1")
    implementation("com.google.android.gms:play-services-appset:16.0.0")
    implementation("com.google.android.gms:play-services-ads-identifier:18.1.0")
    implementation("com.google.android.gms:play-services-basement:18.1.0")
}

2.3 Configure android/app/src/main/AndroidManifest.xml

Add required permissions and AdMob Application ID:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <!-- Required permissions -->
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:label="Your App Name"
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher"
        tools:replace="android:label">

        <!-- AdMob Application ID (REQUIRED) -->
        <!-- Replace with your actual AdMob App ID for production -->
        <!-- Test ID: ca-app-pub-3940256099942544~3347511713 -->
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-3940256099942544~3347511713" />

        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- ... rest of activity config ... -->
        </activity>
    </application>
</manifest>

⚠️ Important: Replace the test AdMob App ID with your production App ID from your AdMob account.


Step 3: Initialize the SDK in Your Flutter App

3.1 Basic Initialization

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

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    
    // Initialize SDK after first frame
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _initializeSdk();
    });
  }

  void _initializeSdk() async {
    try {
      // Wait for activity to be ready
      await Future.delayed(const Duration(milliseconds: 500));
      
      if (!mounted) return;
      
      await JustbaatAds.initialize(
        companyId: 'your-company-id',  // Replace with your company ID
        onSdkReady: () {
          print('JustBaat Ads SDK is ready!');
          // SDK is initialized and ready to use
        },
      );
    } catch (e, stackTrace) {
      print('Error initializing SDK: $e');
      print('Stack trace: $stackTrace');
      // Handle initialization error
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    // Optional: onActivityResumed() is currently a no-op
    if (state == AppLifecycleState.resumed) {
      JustbaatAds.onActivityResumed();
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Your App',
      home: HomePage(),
    );
  }
}

Key Points:

  • ✅ Initialize SDK after the first frame using addPostFrameCallback
  • ✅ Wait 500ms before initialization to ensure Activity is ready
  • ✅ Load/show ads inside onSdkReady (or after it fires)
  • ✅ Handle errors gracefully
  • ℹ️ JustbaatAds.onActivityResumed() is optional (currently a no-op)

Step 4: Implement Ad Types

4.1 Banner Ads

Banner ads are displayed as widgets in your Flutter UI:

import 'package:justbaat_ads/justbaat_ads.dart';

BannerAdWidget(
  divId: 'banner_container_first',  // Must match your config.json
  height: 50,  // Height in logical pixels
  onAdLoaded: () {
    print('Banner ad loaded successfully!');
  },
  onAdFailed: (error) {
    print('Banner ad failed: $error');
  },
)

4.2 Interstitial Ads

// Load the ad first
JustbaatAds.loadInterstitial(
  placementId: 'interstitial_placement',  // Must match your config.json
  onAdLoaded: () {
    print('Interstitial ad loaded!');
    // Now you can show it
  },
  onAdFailed: (error) {
    print('Interstitial failed to load: $error');
  },
);

// Show the ad (call after loading)
JustbaatAds.showInterstitial(
  placementId: 'interstitial_placement',
  enableClickCounting: true,  // Track clicks
  threshold: 1,  // Minimum clicks before showing
  onAdDismissed: () {
    print('Interstitial ad dismissed');
    // User closed the ad
  },
  onAdFailed: (error) {
    print('Interstitial failed to show: $error');
  },
);

4.3 Rewarded Ads

// Load the ad
JustbaatAds.loadRewarded(
  placementId: 'rewarded_placement',  // Must match your config.json
  onAdLoaded: () {
    print('Rewarded ad loaded!');
  },
  onAdFailed: (error) {
    print('Rewarded failed to load: $error');
  },
);

// Show the ad
JustbaatAds.showRewarded(
  placementId: 'rewarded_placement',
  enableClickCounting: true,
  threshold: 5,  // Minimum clicks before showing
  onUserEarnedReward: (reward) {
    print('Reward earned: ${reward.amount} ${reward.type}');
    // Give reward to user
  },
  onAdDismissed: () {
    print('Rewarded ad dismissed');
  },
  onAdFailedToShow: (error) {
    print('Rewarded failed to show: $error');
  },
);

4.4 Native Ads

Native ads are displayed as widgets:

NativeAdWidget(
  divId: 'native_ad_container',  // Must match your config.json
  height: 300,  // Height in logical pixels
  onAdLoaded: () {
    print('Native ad loaded!');
  },
  onAdFailed: (error) {
    print('Native ad failed: $error');
  },
)

4.5 App Open Ads

// Load the ad (typically done during app initialization)
JustbaatAds.loadAppOpen(
  onAdLoaded: () {
    print('App Open ad loaded!');
  },
  onAdFailed: (error) {
    print('App Open failed to load: $error');
  },
);

// Show the ad (typically when app opens)
JustbaatAds.showAppOpen(
  onAdDismissed: () {
    print('App Open ad dismissed');
  },
  onAdFailedToShow: () {
    print('App Open failed to show');
  },
);

Configuration Requirements:

  1. Company ID: Must match the companyId passed to JustbaatAds.initialize()
  2. divId: For Banner and Native ads, must match the divId in your widgets
  3. placementId: For Interstitial and Rewarded ads, must match the placementId in your code
  4. Ad Unit IDs: Configured in your config.json for each ad network (Google AdMob, Unity Ads)

Step 6: Important Notes

6.1 Cache Behavior

  • ✅ Fixed: Each companyId now has its own cache (fixed in latest version)
  • ✅ Cache duration: 24 hours
  • ✅ Cache is stored in SharedPreferences: ad_config_prefs
  • ⚠️ Important: If you change companyId, the SDK will fetch fresh config for that company

6.2 Activity Lifecycle

  • JustbaatAds.onActivityResumed() is optional — it currently performs no active work.
  • Implement WidgetsBindingObserver and call it on resume only if your integration needs it.

6.3 Error Handling

Always handle errors gracefully:

try {
  await JustbaatAds.initialize(companyId: 'your-id', onSdkReady: () {});
} catch (e) {
  // Log error, show user-friendly message, or use fallback
  print('SDK initialization failed: $e');
}

6.4 Testing

  • Use test AdMob App ID during development: ca-app-pub-3940256099942544~3347511713
  • Use test ad unit IDs from AdMob console
  • Test on real devices (not just emulators)
  • Test with different network conditions

Step 7: Troubleshooting

Issue: App crashes on startup

Solution:

  1. Check if AdMob App ID is added to AndroidManifest.xml
  2. Verify companyId is correct
  3. Check logcat: adb logcat | grep -E "(JustbaatAdsPlugin|AdSdkManager|AndroidRuntime)"

Issue: Ads not loading

Solution:

  1. Verify divId/placementId matches your config.json
  2. Check network connectivity
  3. Verify ad unit IDs are correct in config.json
  4. Check logcat for specific error messages

Issue: Wrong ads showing for different companyId

Solution:

  • This was fixed in the latest version
  • Each companyId now has its own cache
  • Clear app data or wait for cache to expire (24 hours)

Issue: Build errors

Solution:

  1. Ensure Android Gradle Plugin is 8.6.0+
  2. Ensure Kotlin version is 2.1.0+
  3. Ensure SDK module is included in settings.gradle
  4. Run flutter clean and rebuild

Step 8: Production Checklist

Before releasing to production:

  • Replace test AdMob App ID with production App ID
  • Replace test ad unit IDs with production ad unit IDs
  • Verify all divId and placementId values match config.json
  • Test all ad types on real devices
  • Test with different network conditions
  • Verify error handling works correctly
  • Test app lifecycle (background/foreground)
  • Verify ads comply with AdMob policies
  • Test with your actual companyId
  • Monitor ad performance in AdMob console

Step 9: Example Complete Implementation

See flutter_plugin/example for a complete working example with all ad types implemented.


Support

For issues or questions:

  1. Check logcat for error messages
  2. Verify configuration matches this guide
  3. Test with the example app first
  4. Review BRIDGE_VERIFICATION.md for bridge status

Version Information

  • Plugin Version: 1.1.1
  • SDK Version: 1.1.1 (Next-Gen, ads-mobile-sdk 1.2.1)
  • Flutter Support: >=3.0.0
  • Android Support: minSdk 24+

Last Updated: July 2026

Make sure your ad configuration is properly set up on the server with the correct divId and placementId values.

Example

See the example/ directory for a complete example app.

License

MIT License

Copyright (c) 2026 JustBaat

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Libraries

justbaat_ads