Skip to main content

Implementing InMobi GDPR Consent with Google AdMob Mediation

 Mobile publishers operating in the EEA (European Economic Area) frequently encounter a silent revenue killer: low fill rates from mediation partners despite having a fully compliant Consent Management Platform (CMP).

One of the most common friction points occurs between Google AdMob and InMobi. While AdMob’s User Messaging Platform (UMP) correctly collects TCF v2.0 (Transparency and Consent Framework) signals, the InMobi adapter does not always automatically ingest these signals from the device's shared preferences.

If InMobi does not receive an explicit consent object, it defaults to a non-consented state. This results in the rejection of personalized ad requests, plummeting eCPM and fill rates. This guide details how to manually construct the required JSON consent object and inject it into the InMobi SDK to ensure revenue continuity.

The Root Cause: Implicit vs. Explicit Signaling

To fix the issue, we must understand the disconnect in the mediation chain.

When a user grants consent via a CMP (like Google UMP), the consent string is stored in the device's default storage (SharedPreferences on Android, UserDefaults on iOS) under the standard IAB key IABTCF_TCString.

Ideally, mediation adapters act as listeners. They should detect this string and pass it to their underlying SDKs. However, the communication between the AdMob mediation layer and the InMobi SDK is not always synchronous.

InMobi requires consent to be set via updateGDPRConsent before the ad request is generated. If the adapter initializes and requests an ad before reading the shared preferences, the request goes out "naked" (without consent). By the time the adapter catches up, the impression opportunity is lost.

To guarantee compliance and revenue, you must bypass the adapter's auto-detection and force-feed the consent data directly to the InMobi SDK immediately after the CMP gathers user input.

The Solution: Manual Consent Injection

The fix involves intercepting the TCF string from local storage and explicitly calling the InMobi GDPR API. This must be done in your application logic immediately after the CMP signals that consent has been gathered.

Android Implementation (Kotlin)

On Android, we read the IABTCF_TCString from PreferenceManager and construct a JSONObject.

Prerequisites:

  • Google Mobile Ads SDK (AdMob)
  • InMobi SDK
  • InMobi Adapter
import android.content.Context
import androidx.preference.PreferenceManager
import com.inmobi.sdk.InMobiSdk
import org.json.JSONException
import org.json.JSONObject

object InMobiConsentManager {

    /**
     * Call this method immediately after your CMP (e.g., UMP) 
     * returns a success callback for consent gathering.
     */
    fun pushConsentToInMobi(context: Context) {
        val prefs = PreferenceManager.getDefaultSharedPreferences(context)
        
        // 1. Retrieve the TCF v2.0 String stored by the CMP
        val gdprConsentString = prefs.getString("IABTCF_TCString", "")
        
        // 2. Check GDPR applicability (Usually usually stored as IABTCF_gdprApplies)
        // 1 = GDPR applies, 0 = Does not apply. Default to safe side (1) if unsure in EU.
        val gdprApplies = prefs.getInt("IABTCF_gdprApplies", 1)

        if (!gdprConsentString.isNullOrEmpty()) {
            try {
                // 3. Construct the JSON Object specific to InMobi's requirement
                val consentObject = JSONObject()
                
                // "1" indicates GDPR is applicable
                consentObject.put(InMobiSdk.IM_GDPR_CONSENT_AVAILABLE, if (gdprApplies == 1) "true" else "false")
                
                // Pass the actual IAB string
                consentObject.put("gdpr_consent", gdprConsentString)

                // 4. Force update the InMobi SDK
                InMobiSdk.updateGDPRConsent(consentObject)
                
            } catch (e: JSONException) {
                // Log error for AdOps/Crashlytics
                System.err.println("Failed to construct InMobi consent JSON: ${e.message}")
            }
        }
    }
}

iOS Implementation (Swift)

On iOS, the concept is identical, but we access UserDefaults and use a standard NSMutableDictionary.

import Foundation
import InMobiSDK

class InMobiConsentManager {
    
    /// Call this immediately after UMP/CMP completion handler
    static func pushConsentToInMobi() {
        let defaults = UserDefaults.standard
        
        // 1. Retrieve the TCF string
        guard let tcfString = defaults.string(forKey: "IABTCF_TCString") else {
            print("InMobi Consent: No TCF string found in UserDefaults.")
            return
        }
        
        // 2. Check applicability
        let gdprApplies = defaults.integer(forKey: "IABTCF_gdprApplies")
        
        // 3. Prepare the dictionary
        let consentDict: NSMutableDictionary = [:]
        
        // InMobi expects "1" or "0" (String) or boolean logic for applicability
        // Using "1" strictly to denote applicability
        consentDict.setValue(gdprApplies == 1 ? "1" : "0", forKey: "gdpr")
        
        // Pass the actual consent string
        consentDict.setValue(tcfString, forKey: "gdpr_consent")
        
        // 4. Update the SDK
        IMSdk.updateGDPRConsent(consentDict as? [AnyHashable : Any])
    }
}

Deep Dive: The JSON Structure

The structure of the data passed to updateGDPRConsent is non-negotiable. If the keys are misspelled, the SDK ignores the update.

  1. gdpr (or IM_GDPR_CONSENT_AVAILABLE constant): This signals whether the user is located in a jurisdiction where GDPR enforcement is required.

    • Value: It typically accepts a string "1" (true) or "0" (false). In Kotlin, utilizing the constant InMobiSdk.IM_GDPR_CONSENT_AVAILABLE is safer than hardcoding the string key "gdpr".
  2. gdpr_consent: This is the payload. It must be the exact raw string generated by the IAB TCF framework (e.g., COvFyGBOvFyGB...).

    • Crucial Detail: Do not attempt to decode or parse this string yourself. Pass it raw. The InMobi server-side logic parses the bitfield to determine which vendors and purposes are allowed.

Timing and Race Conditions

The most common implementation error is timing.

If you initialize AdMob (which initializes the InMobi adapter) before the consent string is written to disk and pushed to InMobi, the first few ad requests will fail GDPR checks.

The Correct Initialization Flow:

  1. Launch App.
  2. Initialize CMP (e.g., UMP requestConsentInfoUpdate).
  3. Wait for the user to accept/manage options.
  4. Callback fires.
  5. IMMEDIATELY run InMobiConsentManager.pushConsentToInMobi().
  6. THEN initialize the Google Mobile Ads SDK (MobileAds.initialize).

By placing the InMobi update strictly before the Mobile Ads initialization, you ensure that when the adapter wakes up, the InMobi singleton already holds the correct compliance data.

Handling "Do Not Sell" (CCPA/GPP)

While this article focuses on GDPR, InMobi also requires explicit flags for CCPA (California Consumer Privacy Act). If you are using the Global Privacy Platform (GPP), the logic is similar but uses the do_not_sell key.

To handle US privacy compliance alongside GDPR within the same object:

// Example extension for CCPA
consentObject.put("do_not_sell", "false") // If user has consented to selling data

Troubleshooting: Zero Fill in EU

If you have implemented the code above but still see zero fill in InMobi reports for EU traffic, check the following:

  1. CMP Configuration: Ensure your CMP (e.g., Google Funding Choices) actually includes InMobi in the vendor list. If InMobi is not selected in the CMP UI, the TCF string will technically be valid, but it will contain a "0" bit for the InMobi vendor ID, legally preventing them from serving ads.
  2. Logcat/Console Inspection: Search logs for [InMobi] tags. If you see warnings regarding "Missing Consent" or "GDPR applies but no consent data," your injection logic is firing too late.
  3. COPPA: If your app is flagged as "Child Directed" in the AdMob console or via code configuration, GDPR consent is often overridden by child protection laws, disabling behavioral targeting entirely.

Conclusion

Relying on mediation adapters to "magically" handle complex compliance signals is a strategy that leads to revenue leakage. For networks like InMobi, explicit data handling is required. By manually reading the IABTCF_TCString and injecting it into the InMobi SDK prior to ad initialization, you ensure compliance and maximize your fill rates across the European market.