광고 수익 측정

수익원을 측정하면 사용자의 평생 가치를 파악하고 앱 비즈니스를 성장시키는 데 도움이 됩니다. 이 가이드에서는 플랫폼의 광고 수익 측정을 설정하는 방법을 설명합니다.

광고 수익 측정을 설정하고 나면 다음 작업을 수행할 수 있습니다.

시작하기 전에

아직 완료하지 않았다면 다음 작업을 완료해야 합니다.

  1. 애널리틱스 시작하기의 설명대로 프로젝트와 앱을 설정합니다.

  2. Firebase 프로젝트를 Google 애널리틱스 계정에 연결했는지 확인합니다.

  3. 앱에 Android SDK v17.6.0 이상 또는 Apple 플랫폼 SDK v6.34.0 이상이 포함되어 있는지 확인합니다.

구현

Google 애널리틱스를 사용하여 AdMob, AppLovin, ironSource와 같은 수익 창출 플랫폼에 광고를 게재해 발생한 광고 수익을 측정할 수 있습니다. 광고 수익을 측정하려면 사용자가 앱에서 광고를 볼 때마다 ad_impression 이벤트를 로깅해야 합니다. 이러한 이벤트에는 광고 플랫폼, 소스, 통화, 값과 같은 세부정보가 포함됩니다.

AdMob

AdMob 플랫폼을 사용하는 경우 AdMob 앱을 Firebase와 애널리틱스에 연결하여 광고 수익 자동 측정을 사용 설정합니다. Google 애널리틱스용 Firebase SDK는 사용자가 광고 노출을 볼 때마다 ad_impression 이벤트를 자동으로 로깅합니다.

기타 광고 수익 창출 플랫폼

AppLovin 및 ironSource와 같은 플랫폼은 노출 수준의 수익 데이터를 제공하므로 Google 애널리틱스 ad_impression 이벤트를 로깅하는 데 사용할 수 있습니다.

다음 섹션에서는 몇 가지 광고 수익 창출 플랫폼의 구현 예를 보여줍니다.

AppLovin

Swift

참고: 이 Firebase 제품은 macOS 대상에서 사용할 수 없습니다.
func didPayRevenue(_ impressionData: MAAd?) {
  if let impressionData = impressionData {
    Analytics.logEvent(
      AnalyticsEventAdImpression,
      parameters: [
        AnalyticsParameterAdPlatform: "AppLovin",
        AnalyticsParameterAdUnitName: impressionData.adUnitIdentifier,
        AnalyticsParameterAdFormat: impressionData.format,
        AnalyticsParameterValue: impressionData.revenue,
        AnalyticsParameterCurrency: "USD",  // All Applovin revenue is sent in USD
        AnalyticsParameterAdSource: impressionData.networkName,
      ])
  }
}

Objective-C

참고: 이 Firebase 제품은 macOS 대상에서 사용할 수 없습니다.
- (void)didPayRevenueForAd:(MAAd *)impressionData {
    [FIRAnalytics logEventWithName:kFIREventAdImpression
                    parameters: @{
                        kFIRParameterAdPlatform: @"AppLovin",
                        kFIRParameterAdSource: impressionData.networkName,
                        kFIRParameterAdFormat: impressionData.format,
                        kFIRParameterAdUnitName: impressionData.adUnitIdentifier,
                        kFIRParameterCurrency: @"USD", // All Applovin revenue is sent in USD
                        kFIRParameterValue: impressionData.revenue
                    }];
}

Kotlin+KTX

override fun onAdRevenuePaid(impressionData: MaxAd?) {
    impressionData?.let {
        firebaseAnalytics = Firebase.analytics
        firebaseAnalytics.logEvent(FirebaseAnalytics.Event.AD_IMPRESSION) {
            param(FirebaseAnalytics.Param.AD_PLATFORM, "appLovin")
            param(FirebaseAnalytics.Param.AD_UNIT_NAME, impressionData.adUnitId)
            param(FirebaseAnalytics.Param.AD_FORMAT, impressionData.format.label)
            param(FirebaseAnalytics.Param.AD_SOURCE, impressionData.networkName)
            param(FirebaseAnalytics.Param.VALUE, impressionData.revenue)
            param(FirebaseAnalytics.Param.CURRENCY, "USD") // All Applovin revenue is sent in USD
        }
    }
}

Java

@Override
public void onAdRevenuePaid(MaxAd impressionData) {

    double revenue = impressionData.getRevenue(); // In USD

    mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
    Bundle params = new Bundle();
    params.putString(FirebaseAnalytics.Param.AD_PLATFORM, "appLovin");
    params.putString(FirebaseAnalytics.Param.AD_SOURCE, impressionData.getNetworkName());
    params.putString(FirebaseAnalytics.Param.AD_FORMAT, impressionData.getFormat().getLabel());
    params.putString(FirebaseAnalytics.Param.AD_UNIT_NAME, impressionData.getAdUnitId());
    params.putDouble(FirebaseAnalytics.Param.VALUE, revenue);
    params.putString(FirebaseAnalytics.Param.CURRENCY, "USD"); // All Applovin revenue is sent in USD
    mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.AD_IMPRESSION, params);
}

Unity

// Attach callbacks based on the ad format(s) you are using
MaxSdkCallbacks.Interstitial.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
MaxSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
MaxSdkCallbacks.Banner.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
MaxSdkCallbacks.MRec.OnAdRevenuePaidEvent += OnAdRevenuePaidEvent;
private void OnAdRevenuePaidEvent(string adUnitId, MaxSdkBase.AdInfo impressionData)
{
double revenue = impressionData.Revenue;
var impressionParameters = new[] {
  new Firebase.Analytics.Parameter("ad_platform", "AppLovin"),
  new Firebase.Analytics.Parameter("ad_source", impressionData.NetworkName),
  new Firebase.Analytics.Parameter("ad_unit_name", impressionData.AdUnitIdentifier),
  new Firebase.Analytics.Parameter("ad_format", impressionData.AdFormat),
  new Firebase.Analytics.Parameter("value", revenue),
  new Firebase.Analytics.Parameter("currency", "USD"), // All AppLovin revenue is sent in USD
};
Firebase.Analytics.FirebaseAnalytics.LogEvent("ad_impression", impressionParameters);
}

ironSource

Swift

참고: 이 Firebase 제품은 macOS 대상에서 사용할 수 없습니다.
func impressionDataDidSucceed(_ impressionData: ISImpressionData!) {
  Analytics.logEvent(
    AnalyticsEventAdImpression,
    parameters: [
      AnalyticsParameterAdPlatform: "ironSource",
      AnalyticsParameterAdSource: impressionData.ad_network ?? "No ad_network",
      AnalyticsParameterAdFormat: impressionData.ad_unit ?? "No ad_unit",
      AnalyticsParameterAdUnitName: impressionData.instance_name ?? "No instance_name",
      AnalyticsParameterCurrency: "USD",
      AnalyticsParameterValue: impressionData.revenue ?? 0,
    ])
}

Objective-C

참고: 이 Firebase 제품은 macOS 대상에서 사용할 수 없습니다.
- (void)impressionDataDidSucceed:(ISImpressionData *)impressionData {
  [FIRAnalytics logEventWithName:kFIREventAdImpression
                      parameters:@{
                        kFIRParameterAdPlatform: @"ironSource",
                        kFIRParameterAdSource: impressionData.ad_network,
                        kFIRParameterAdFormat: impressionData.ad_unit,
                        kFIRParameterAdUnitName: impressionData.instance_name,
                        kFIRParameterCurrency: @"USD",
                        kFIRParameterValue: impressionData.revenue
                      }];
}

Kotlin+KTX

override fun onImpressionSuccess(impressionData: ImpressionData) {
    // The onImpressionSuccess will be reported when the rewarded video and interstitial ad is
    // opened.
    // For banners, the impression is reported on load success. Log.d(TAG, "onImpressionSuccess" +
    // impressionData)
    firebaseAnalytics = Firebase.analytics
    firebaseAnalytics.logEvent(FirebaseAnalytics.Event.AD_IMPRESSION) {
        param(FirebaseAnalytics.Param.AD_PLATFORM, "ironSource")
        param(FirebaseAnalytics.Param.AD_SOURCE, impressionData.adNetwork)
        param(FirebaseAnalytics.Param.AD_FORMAT, impressionData.adUnit)
        param(FirebaseAnalytics.Param.AD_UNIT_NAME, impressionData.instanceName)
        param(FirebaseAnalytics.Param.CURRENCY, "USD")
        param(FirebaseAnalytics.Param.VALUE, impressionData.revenue)
    }
}

Java

@Override
public void onImpressionSuccess(ImpressionData impressionData) {
    // The onImpressionSuccess will be reported when the rewarded video and interstitial ad is opened.
    // For banners, the impression is reported on load success. Log.d(TAG, "onImpressionSuccess" + impressionData);
    mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
    if (impressionData != null) {
        Bundle bundle = new Bundle();
        bundle.putString(FirebaseAnalytics.Param.AD_PLATFORM, "ironSource");
        bundle.putString(FirebaseAnalytics.Param.AD_SOURCE, impressionData.getAdNetwork());
        bundle.putString(FirebaseAnalytics.Param.AD_FORMAT, impressionData.getAdUnit());
        bundle.putString(FirebaseAnalytics.Param.AD_UNIT_NAME, impressionData.getInstanceName());
        bundle.putString(FirebaseAnalytics.Param.CURRENCY, "USD");
        bundle.putDouble(FirebaseAnalytics.Param.VALUE, impressionData.getRevenue());
        mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.AD_IMPRESSION, bundle);
    }
}

Unity

private void ImpressionSuccessEvent(IronSourceImpressionData impressionData) {
  if (impressionData != null) {
      Firebase.Analytics.Parameter[] AdParameters = {
        new Firebase.Analytics.Parameter("ad_platform", "ironSource"),
        new Firebase.Analytics.Parameter("ad_source", impressionData.adNetwork),
        new Firebase.Analytics.Parameter("ad_unit_name", impressionData.getInstanceName),
        new Firebase.Analytics.Parameter("ad_format", impressionData.getAdUnit),
        new Firebase.Analytics.Parameter("currency","USD"),
        new Firebase.Analytics.Parameter("value", impressionData.getRevenue)
      };
      Firebase.Analytics.FirebaseAnalytics.LogEvent("ad_impression", AdParameters);
  }
}

구현 관련 고려사항

Google Ads에서 ad_impression을 처리하도록 하려면 currencyvalue 매개변수를 모두 포함해야 합니다(아래 설명 참조). 두 매개변수가 가능한 한 정확해야 사용자를 과대평가하거나 과소평가하지 않을 수 있습니다.

통화 매개변수

currency 매개변수(iOS+ | Android | Unity)는 세 글자의 ISO_4217 형식 문자열(예: "USD")로 전송되어야 합니다. 일부 광고 수익 창출 플랫폼에서는 통화가 생략되므로 매개변수를 하드코딩해야 할 수도 있습니다.

값 매개변수

value 매개변수(iOS+ | Android | Unity)는 소수점 구분 기호로 점을 사용하여 전송되어야 합니다. 일부 플랫폼에서 수신한 값은 위 필수 형식에 맞게 변환해야 할 수도 있습니다. 일부 플랫폼은 숫자 형식을 현지화하고 쉼표를 소수점 구분 기호로 사용합니다. 경우에 따라서는 플랫폼에서 값을 아예 전송하지 못할 수 있습니다.

또한 이 값은 double 또는 long과 같은 숫자 유형이어야 합니다. 예를 들어 1000.01, 0.001, 1.00은 모두 유효합니다.

검증

Google 애널리틱스는 개발 주기 전체에 걸쳐 구현의 유효성을 검증하는 여러 기능을 제공합니다.

  1. DebugView
    구현을 처음 테스트할 때 DebugView를 사용하여 Console에서 테스트 ad_impression 데이터를 확인합니다. ad_impression 이벤트를 선택하면 화면 오른쪽에 있는 Parameters 패널에서 전송하는 매개변수를 검토할 수 있습니다. 이렇게 하면 올바른 정보가 처리되고 있는지 확인할 수 있습니다.

  2. 실시간
    앱을 배포한 후 Google 애널리틱스 실시간 보고서를 사용하여 구현이 올바르게 작동하는지 확인합니다. 실시간 보고서에서 이벤트 이름별 이벤트 수 카드를 확인하고 ad_impression을 선택하여 최근 30분 동안의 이벤트 및 매개변수 세부정보를 확인합니다.

  3. BigQuery
    BigQuery Export를 사용하여 1일 이상의 ad_impression 이벤트 샘플을 추출합니다. 이 추출된 샘플을 사용하여 0 또는 설정되지 않은 값과 같은 문제를 찾고 처리되지 않은 사용 사례에 맞게 코드에 수정사항을 적용하세요.

다음 단계

Firebase Console에서 이동하거나 애널리틱스 콘솔에 연결된 애널리틱스 속성을 통해 애널리틱스 대시보드로 이동합니다. 광고 수익은 사용자당 평균 수익(ARPU), 평생 가치(LTV) 등의 측정항목에 반영됩니다.