Tech 8 min read

iOS Google Ads Conversion Tracking: Why Adjust Alone Isn't Enough

Someone from the ad team told me: “Set up Google Ads iOS conversion tracking.”

I figured since Adjust was already in, updating the Adjust SDK would be enough.

Turned out that was completely wrong. You need all three: Adjust SDK + Firebase SDK + Adjust ODM plugin. And on top of that, you have to request a whitelist registration on the Adjust side.

Here’s a writeup on how iOS ad measurement has gotten more complicated than you’d expect.

Why iOS Ad Measurement Got Complex

ATT Restrictions Since iOS 14.5

Since iOS 14.5 (April 2021), getting the IDFA (Identifier for Advertisers) requires explicit user consent. This is ATT (App Tracking Transparency).

When a user selects “Don’t Allow Tracking,” the app can no longer access the IDFA. Consent rates are generally around 20–30% in practice.

In other words, the old IDFA-based measurement approach has mostly stopped working.

Why the Old Method Doesn’t Work Anymore

Before iOS 14.5:

  • App → get IDFA → send to Google Ads → “Oh, this is the person who clicked that ad”

Since iOS 14.5:

  • 20–30% of users → IDFA accessible (measurable)
  • 70–80% of users → no IDFA (unmeasurable)

From Google Ads’ perspective, measurement only works for the minority. That makes it impossible to evaluate ad effectiveness.

Hence the need for an alternative: “On-Device Conversion.”

The Full Picture of Measurement Routes

Google Ads iOS conversion tracking has two main routes:

Route via Adjust

In-app event

Adjust SDK + ODM plugin

Firebase Analytics (for Google On-Device Conversion)

Adjust server (S2S integration)

Google Ads

Characteristics:

  • Natural choice if you’re already using Adjust
  • Strengths as an MMP (supports multiple ad platforms)
  • Requires ICM whitelist registration on the Adjust side

Route via Firebase

In-app event

Firebase SDK (v11.14.0+)

Firebase Analytics (for Google On-Device Conversion)

Google Ads

Characteristics:

  • Self-contained within the Google ecosystem
  • Relatively simple setup
  • A viable option if you’re starting fresh

Which Should You Choose?

SituationRoute
Already using AdjustVia Adjust
Using Firebase onlyVia Firebase
Either worksVia Firebase (simpler setup)

Important: Whichever you choose, Firebase Analytics + Google On-Device Conversion (ODM) integration is mandatory. This is a Google Ads requirement.

The “Adjust Is Enough” Misconception

This is where I got tripped up at first.

I thought “Adjust is already in, so just updating the Adjust SDK should do it.”

But what’s actually required:

  1. Adjust SDK updated to v5.4.1 or higher
  2. Adjust ODM plugin added (for Google On-Device Measurement)
  3. Firebase SDK v11.14.0 or higher
  4. Firebase ↔ Google Ads integration configured
  5. ICM whitelist registration requested from Adjust

Just having “Adjust SDK installed” isn’t enough. Firebase is mandatory too. Only with all of these together does “Google On-Device Conversion” actually work.

Implementation Steps (via Adjust)

1. Update Adjust SDK & Add ODM Plugin

With CocoaPods

Add (or update) the following in your Podfile:

pod 'Adjust', '5.4.1'
pod 'Adjust/AdjustGoogleOdm'
pod 'GoogleAdsOnDeviceConversion', '3.0.0'

If you already have Firebase Analytics 11.14.0+ installed, GoogleAdsOnDeviceConversion will be pulled in as a dependency automatically — no manual addition needed.

Then run pod install:

pod install

With Swift Package Manager

In Xcode, go to File → Add Package Dependencies and add the GitHub repository:

https://github.com/adjust/ios_sdk

Select version 5.4.1 or higher and add AdjustGoogleOdm to your target.

2. Implement the ATT Permission Request

This is the part that displays the tracking permission dialog on iOS 14.5+, asking the user whether to allow tracking.

Swift (AppDelegate):

import AppTrackingTransparency

func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
    requestTrackingAuthorization()
    return true
}

func requestTrackingAuthorization() {
    if #available(iOS 14.5, *) {
        ATTrackingManager.requestTrackingAuthorization { status in
            DispatchQueue.main.async {
                self.initializeAdjust()
            }
        }
    } else {
        initializeAdjust()
    }
}

Timing note: Showing the dialog immediately at launch makes users more likely to deny. Best practice is to show it after the user has understood the app’s value (after 1–2 screens).

3. Initialize Adjust SDK (Flutter/Dart)

import 'package:adjust_sdk/adjust.dart';
import 'package:adjust_sdk/adjust_config.dart';

void initializeAdjust() {
  AdjustConfig config = AdjustConfig(
    '{YourAppToken}',
    AdjustEnvironment.production,  // production for release
  );

  // Very important: wait time for the ATT dialog response
  config.attConsentWaitingInterval = 120;  // 120 seconds

  // Log level (for development)
  config.logLevel = AdjustLogLevel.verbose;

  Adjust.initSdk(config);
}

Setting attConsentWaitingInterval tells the Adjust SDK to wait for the ATT permission status. Forgetting this means ATT-denied users won’t be measured.

4. Verify Firebase SDK & Configure Google Ads Integration

Initialize Firebase Analytics from the Flutter side (usually not needed if Firebase is already set up):

import 'package:firebase_analytics/firebase_analytics.dart';

final analytics = FirebaseAnalytics.instance;

// Example event
await analytics.logEvent(
  name: 'purchase',
  parameters: {
    'currency': 'JPY',
    'value': 980,
    'transaction_id': 'txn_12345',
  },
);

Google Ads settings (dashboard):

  1. Log in to Google Ads
  2. “Tools” → “Conversions”
  3. Create a new conversion action, or duplicate your Android one for iOS
  4. Set the source to “Google Analytics for Firebase”
  5. Select the corresponding Firebase event (e.g. purchase)

5. Configure Google Ads Integration in Adjust

In the Adjust dashboard:

  1. Partner setup → Enable Google Ads
  2. Register the conversion token issued by Google Ads in Adjust
  3. Also send the event to Adjust from the Flutter app:
void trackPurchase(double amount, String currency, String transactionId) {
  // Also record in Adjust
  AdjustEvent event = AdjustEvent('{AdjustPurchaseEventToken}');
  event.setRevenue(amount, currency);
  event.setTransactionId(transactionId);
  Adjust.trackEvent(event);
}

6. ICM Whitelist Registration (Adjust-side Action)

Contact Adjust and provide the following for the target app:

  • iOS App ID (e.g. com.example.myapp)
  • Adjust App Token

Adjust will add it to the ICM (In-App Conversion Measurement) whitelist. Without this, no amount of implementation will start measurement.

Testing and Debugging

Verifying in the Sandbox Environment

The Testing Console in the Adjust dashboard lets you confirm whether events are arriving correctly.

Run the production app on a test device registered in the Testing Console, and events will appear in real time.

// Keep debug logging on
config.logLevel = AdjustLogLevel.verbose;

If you see messages like “Event logged” in the log output, the SDK side is working.

Checking Conversions in Google Ads

Conversion numbers in the Google Ads dashboard take 24–48 hours to reflect after measurement occurs.

Don’t panic when the debug screen shows nothing. Check the next morning — the numbers are often there by then.

Pitfalls and Caveats

1. Adjust SDK Alone Isn’t Enough

This is the biggest point. Firebase SDK integration is mandatory.

There’s a lot of documentation saying “you can measure with Adjust,” and the Firebase part tends to get glossed over. But Firebase Analytics + ODM integration is a Google Ads requirement.

2. Firebase SDK Must Be v11.14.0+

A June 2025 update added a new “event data method.”

Older versions (11.13 and earlier) don’t support this method. Forgetting to update may prevent measurement from starting.

3. Forgetting attConsentWaitingInterval

config.attConsentWaitingInterval = 120;

Without this setting, the Adjust SDK initializes without waiting for ATT permission.

Conversion measurement for ATT-denied users won’t work.

4. ICM Whitelist Registration Isn’t Automatic

You can implement everything on the code side, set up Firebase Analytics, and it still won’t start without the manual registration on Adjust’s end.

If “measurement isn’t working after implementation is complete,” this registration is almost always the culprit.

5. Don’t Forget to Switch Sandbox vs Production

During development:

AdjustEnvironment.sandbox

For production:

AdjustEnvironment.production

If you forget to change this to production at release time, real data won’t be sent to Google Ads.

6. ATT Dialog Timing

Showing the dialog immediately at launch means users are likely to tap “Don’t Allow” without understanding why.

Best practice:

  • Show it after the user has understood the app’s value (2–3 screens in)
  • Or show it at a point where tracking is clearly relevant

Firebase-Only Route (Supplemental)

If you’re not using Adjust, Firebase alone works:

import 'package:firebase_analytics/firebase_analytics.dart';

final analytics = FirebaseAnalytics.instance;

// Send event
await analytics.logEvent(
  name: 'purchase',
  parameters: {
    'currency': 'JPY',
    'value': 9800,
  },
);

Configure Firebase Analytics integration in Google Ads, and ODM (On-Device Measurement) is automatically enabled.

It’s less flexible than Adjust, but the setup is simpler. If you’re starting iOS ad measurement from scratch, going straight to Firebase is a perfectly valid option.

Implementation Checklist

□ Update Adjust SDK to v5.4.1+
□ Add Adjust ODM plugin (Podfile/SPM)
□ Run pod install or update packages
□ Verify Firebase SDK version (v11.14.0+)
□ Implement ATT permission request in AppDelegate
□ Initialize Adjust SDK in Dart (set attConsentWaitingInterval)
□ Send events via Firebase Analytics
□ Enable Google Ads integration in Adjust dashboard
□ Create conversion action in Google Ads
□ Verify event delivery in Testing Console
□ Request ICM whitelist registration from Adjust
□ Set AdjustEnvironment.production for production builds

iOS 14.5+ restricted IDFA tracking, making alternatives necessary for Google Ads conversion measurement. It’s not as simple as “update Adjust SDK” — you need the full trio:

  1. Adjust SDK v5.4.1+ + ODM plugin
  2. Firebase SDK v11.14.0+
  3. Firebase ↔ Google Ads integration

And then manual whitelist registration on the Adjust side.

There’s also a 24–48 hour delay before measurement reflects. Don’t panic when the numbers don’t appear immediately after implementation — check again the next day.

References