1. 简介
开始之前的一些背景信息
如果您是 iOS 应用开发者,一定听说过 iOS 14.5 及更高版本的隐私权更新。为了衡量有意义的安装后转化操作,Apple 提供了 SKAd Network API,可让您衡量广告系列的成效,同时尊重用户隐私。您可以根据自己的业务需求想出最佳方法,利用 SKAd Network 获取有关您广告系列的有意义的数据洞见。在本 Codelab 中,我们将介绍一种示例方法,用于利用 BigQuery 中的 GA4F 数据将应用安装后的收入划分到多个存储桶中,以便您与应用归因合作伙伴进行设置。虽然此 Codelab 使用基于收入的方法,但您也可以使用基于事件或漏斗的方法进行 SKAN 衡量。如需更详细的指导,请参阅此帮助中心。这只是一个示例,并非 Google 的官方建议。您可以根据自己的具体业务需求设计自己的架构
我们打算介绍的内容
- 在 BigQuery 中探索 GA4F 数据
- 查找 0-2 天内完成转化的用户的收入数据
- 将收入数据分组到存储分区中
- 了解每个分桶中的用户分布情况
- 在 Appsflyer SKAN Conversion Studio 中实现存储桶
前提条件
- iOS 应用中的 GA4F SDK ,以及集成的所有收入事件(in_app_purchase 或广告资助收入)
- 已启用 Firebase 到 BigQuery 导出
- 应用归因合作伙伴,也会记录所有收入事件
2. 访问 BigQuery Export
导航到 Google Cloud 数据集
转到 GA4F 中的数据集,方法是依次访问项目设置 >集成 >BigQuery。需要先启用切换开关,启用后,数据集大约需要 48 小时才能可用。您可以点击下方显示的链接,前往 BigQuery
运行一些查询
现在,您已进入 BigQuery,应该会看到生成的每日表格。在下面的示例屏幕截图中,我们看到每天 64 个表格,因此导出作业已经运行了 64 天。如果您是第一次访问该表格,则可能每天只会看到一个显示前一天数据的表格。右侧显示了表架构。如需详细了解这些字段,请点击此处
要开始编写查询,您可以点击查询 >在新标签页中
然后,您可以尝试在新标签页中运行示例查询
3. 分析收入数据
提取安装数据
现在,为了开始构建收入分桶,我们必须先查看过去 24 至 72 小时内安装了应用的用户的数据。通过 SKAd Network 4.0,您可以在 0-2 天内查看数据,而 SKAd Network 3.5 默认允许 24 小时。(您或许可以修改此活动时间范围,一般不超过 72 小时,具体取决于您的应用归因合作伙伴的功能)。当用户安装应用并首次打开该应用时,SDK 会触发 first_open 事件并将其记录在 BigQuery 中。
您可以将 user_pseudo_id(也称为应用实例 ID)用于 BigQuery,因此可以使用以下查询查找这些用户
SELECT
user_pseudo_id,
event_name,
event_date,
event_timestamp
FROM `project_name.dataset_name.events_2023*`
WHERE
event_name = 'first_open'
AND platform = 'IOS'
关于此查询的几点说明
- 请将表名称替换为您从 Google Analytics 导出的表。您可以使用通配符查询多个每日表。例如,2023* 将查询 2023 年的所有数据
- 如果您有许多用户,也可以仅查询过去 30 天的查询,以加快处理速度
- 我们按平台 =“IOS”进行过滤。如果您的 Firebase 项目中有多个 iOS 应用,您还可以为 app_info.firebase_app_id 添加过滤条件,以获取特定应用的数据
提取收入数据
现在,我们来看看查询用户收入的查询。在这种情况下,我们会假设您的收入事件是 in_app_purchase 和 ad_impression。in_app_purchase 带来的收入可在 event_value_usd 中找到,而对于 ad_impression,收入可在事件参数中的 value 参数中找到。如果您不熟悉 BigQuery 中的事件参数,建议您点击此处查看定义,并尝试使用此示例查询(我们的官方参考文档中也介绍了如何从 event_params 中提取值)
SELECT
user_pseudo_id,
event_name,
EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
(
SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
FROM UNNEST(event_params)
WHERE
KEY = 'value'
AND event_name = 'ad_impression'
) AS ad_funded_revenue,
(
SELECT value.string_value
FROM UNNEST(event_params)
WHERE
KEY = 'currency'
AND event_name = 'ad_impression'
) AS ad_revenue_currency,
(
CASE
WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
ELSE 0
END) AS iap_revenue_usd,
FROM `project_name.dataset_name.events_2023*`
WHERE
platform = 'IOS'
AND event_name IN (
'in_app_purchase',
'ad_impression')
我们来了解一下这个查询在执行什么操作。您会注意到
- 在 WHERE 子句中,我们过滤收入事件,因为我们只对这些事件感兴趣,和上次一样,我们要查找 iOS 数据
- 现在,在 SELECT 子句中,我们会获取广告收入事件 (ad_impression) 的价值和币种,如果事件为 in_app_purchase,则会获取 event_value_in_usd
- 如果您发送的是多种币种,则首先需要统一为一种币种,以便进行此分析。在此示例中,我们假设广告收入的币种也为美元
输出结果如下所示(此处隐去了 user_pseudo_id 列)。
组合这些数据
到目前为止,我们已经运行了两个查询,一个用于查找已安装并打开应用的用户的数据,另一个用于查找这些用户的收入。现在,我们来回顾一下之前讨论过 SKAd 广告联盟限制的内容。归因时间范围只能是安装后的 0-2 天。因此,我们需要检查安装和收入事件的时间戳,并仅在相应事件发生在该时间范围内时才获取相关信息。现在,我们来介绍如何将查询合并到一个查询中,查询中每个帖子在两天的安装情况所带来的总收入
#creating the install table
WITH
install_table AS (
SELECT
user_pseudo_id,
event_name,
event_date,
event_timestamp
FROM `project_name.dataset_name.events_2023*`
WHERE
event_name = 'first_open'
AND platform = 'IOS'
),
#creating the revenue table
revenue_table AS (
SELECT
user_pseudo_id,
event_name,
event_timestamp,
EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
(
SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
FROM UNNEST(event_params)
WHERE
KEY = 'value'
AND event_name = 'ad_impression'
) AS ad_funded_revenue,
(
SELECT value.string_value
FROM UNNEST(event_params)
WHERE
KEY = 'currency'
AND event_name = 'ad_impression'
) AS ad_revenue_currency,
(
CASE
WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
ELSE 0
END) AS iap_revenue_usd,
FROM `project_name.dataset_name.events_2023*`
WHERE
platform = 'IOS'
AND event_name IN (
'in_app_purchase',
'ad_impression')
)
SELECT
it.user_pseudo_id AS user_pseudo_id,
#combine ad revenue and IAP revenue, assuming both are in same currency
sum(ifnull(rt.iap_revenue_usd,0) + ifnull(rt.ad_funded_revenue,0)) AS total_revenue,
FROM install_table it
INNER JOIN revenue_table rt
ON it.user_pseudo_id = rt.user_pseudo_id
WHERE
rt.event_timestamp >= it.event_timestamp
AND rt.event_timestamp
<= it.event_timestamp + 86400000000 * 2 #added 86400 000 millisecond as 24 hours, taking for 2 days later
GROUP BY 1
该查询只是尝试按 user_pseudo_id 字段联接安装数据和收入数据,然后我们必须确保时间戳在 2 天内。如果您使用的是 SKAd Network 3.5,默认值为 24 小时,因此您也可以更改条件,以仅包含 1 天的数据
将收入分组
执行上一个查询后,您应该会获得 user_pseudo_id 和总收入
现在,我们需要将这些数据合并到可用于转化价值范围的分桶中。为此,我们将使用 BigQuery 中的 approx_quantiles 函数,该函数会自动为您创建这些范围。在本示例中,我们假设我们想创建 5 个范围,所以只需使用 SELECT approx_quantiles(total_revenue, 5) AS 分区
接下来,我们将其纳入到总体查询中
#creating the install table
WITH
install_table AS (
SELECT
user_pseudo_id,
event_name,
event_date,
event_timestamp
FROM `project_name.dataset_name.events_2023*`
WHERE
event_name = 'first_open'
AND platform = 'IOS'
),
#creating the revenue table
revenue_table AS (
SELECT
user_pseudo_id,
event_name,
event_timestamp,
EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
(
SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
FROM UNNEST(event_params)
WHERE
KEY = 'value'
AND event_name = 'ad_impression'
) AS ad_funded_revenue,
(
SELECT value.string_value
FROM UNNEST(event_params)
WHERE
KEY = 'currency'
AND event_name = 'ad_impression'
) AS ad_revenue_currency,
(
CASE
WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
ELSE 0
END) AS iap_revenue_usd,
FROM `project_name.dataset_name.events_2023*`
WHERE
platform = 'IOS'
AND event_name IN (
'in_app_purchase',
'ad_impression')
),
total_revenue_table AS (
SELECT
it.user_pseudo_id AS user_pseudo_id,
#combine ad revenue and IAP revenue, assuming both are in same currency
sum(ifnull(rt.iap_revenue_usd,0) + ifnull(rt.ad_funded_revenue,0)) AS total_revenue,
FROM install_table it
INNER JOIN revenue_table rt
ON it.user_pseudo_id = rt.user_pseudo_id
WHERE
rt.event_timestamp >= it.event_timestamp
AND rt.event_timestamp
<= it.event_timestamp + 86400000000 * 2 #added 86400 000 millisecond as 24 hours
GROUP BY 1
)
SELECT approx_quantiles(total_revenue, 5) AS buckets FROM total_revenue_table
此查询应将收入划分为 5 个分桶,BigQuery 会尽量保持一致的百分位分布
使用这些存储桶分析用户分布情况
如果您想了解每个存储分区中的用户分布情况,则可以选择执行此步骤。在本例中,上一个查询返回的分桶范围为
- 0.1
- 0.5
- 2
- 2.5
- 5 [不应在范围配置中使用最后一个值]
对于最终范围,我们应忽略最后一个存储分区 5,因为它通常是最大值,我们可以将 2.5 视为最后一个范围。这是因为应用归因服务提供商往往使用范围的平均值来计算广告支出回报率,因此必须排除离群值以获得更均匀的计算结果。
现在,我们尝试查看所有范围内每个日期的用户数,以便了解每个存储桶中的用户每日量。我们可以使用以下示例查询来实现此目的,您可以将存储桶值替换为实际数据,查询将如下所示
#creating the install table
WITH
install_table AS (
SELECT
user_pseudo_id,
event_name,
event_date,
event_timestamp
FROM `project_name.dataset_name.events_2023*`
WHERE
event_name = 'first_open'
AND platform = 'IOS'
),
#creating the revenue table
revenue_table AS (
SELECT
user_pseudo_id,
event_name,
event_timestamp,
EXTRACT(date FROM Parse_datetime('%Y%m%d', event_date)) AS event_date,
(
SELECT COALESCE(value.int_value, value.float_value, value.double_value, NULL)
FROM UNNEST(event_params)
WHERE
KEY = 'value'
AND event_name = 'ad_impression'
) AS ad_funded_revenue,
(
SELECT value.string_value
FROM UNNEST(event_params)
WHERE
KEY = 'currency'
AND event_name = 'ad_impression'
) AS ad_revenue_currency,
(
CASE
WHEN event_name = 'in_app_purchase' THEN event_value_in_usd
ELSE 0
END) AS iap_revenue_usd,
FROM `project_name.dataset_name.events_2023*`
WHERE
platform = 'IOS'
AND event_name IN (
'in_app_purchase',
'ad_impression')
),
total_revenue_table AS (
SELECT
it.user_pseudo_id AS user_pseudo_id,
rt.event_date,
#combine ad revenue and IAP revenue, assuming both are in same currency
sum(ifnull(rt.iap_revenue_usd,0) + ifnull(rt.ad_funded_revenue,0)) AS total_revenue,
FROM install_table it
INNER JOIN revenue_table rt
ON it.user_pseudo_id = rt.user_pseudo_id
WHERE
rt.event_timestamp >= it.event_timestamp
AND rt.event_timestamp
<= it.event_timestamp + 86400000000 * 2 #added 86400 000 millisecond as 24 hours
GROUP BY 1, 2
)
SELECT
event_date,
sum(CASE WHEN total_revenue BETWEEN 0 AND 0.1 THEN 1 ELSE 0 END) AS Bucket1,
sum(CASE WHEN total_revenue BETWEEN 0.1 AND 0.5 THEN 1 ELSE 0 END) AS Bucket2,
sum(CASE WHEN total_revenue BETWEEN 0.5 AND 2 THEN 1 ELSE 0 END) AS Bucket3,
sum(CASE WHEN total_revenue BETWEEN 2 AND 2.5 THEN 1 ELSE 0 END) AS Bucket4,
sum(CASE WHEN total_revenue > 2.5 THEN 1 ELSE 0 END) AS Bucket5
FROM total_revenue_table
GROUP BY 1 ORDER BY 1 DESC
它应返回每个收入范围内每天的用户,如下所示。如果您发现任何分桶中的数字非常低,或者分布普遍不均匀,则可能需要调整分桶数量并重新运行查询。
SKAd Network 4.0 简介
SKAd Network 4.0 提供多种转化时间范围,最长可达 2 天、3-7 天和 8-35 天。在上述方法中,您还可以轻松更改时间范围,以便分析这些其他场景的数据。您还可以使用粗粒度值,包括 LOW、MEDIUM 和 HIGH。再次强调,如果您想使用这种方法,可以将其视为 3 个存储分区,因此,通过将存储分区数量更改为 3,您可以获得“低”“中”和“高”的阈值
4. 使用归因服务提供商进行部署
此指南可能会因具体平台而异。如需了解与此有关的最新信息,请与平台代表联系。在本例中,我们将探讨目前如何在 AppsFlyer 上部署此功能
在我们之前运行的查询中,我们得到的最终输出范围如下所示
- 范围 1:0 到 0.1
- 范围 2:0.1 到 0.5
- 范围 3:0.5 到 2
- 范围 4:2 到 2.5
请注意,我们决定忽略上一个收入范围,因为这是一个离群值,导致应用归因提供商的平均计算结果出现偏差。
AppsFlyer 提供 SKAN Conversion Studio,您可以通过该工具轻松将此值直接输入界面中。您可以直接使用 4.0,也可以使用“自定义”模式(如果您使用的是 3.5),并添加“收入”衡量指标。然后,您只需添加在之前的分析中计算出的收入范围即可。
Google Ads 最佳做法和心得
如果您在 Google Ads 上投放广告系列,并通过 SKAdNetwork 转化价值架构衡量效果,我们建议您采取以下措施
- 请确保您在 Google Ads 中使用的转化时间范围与您在应用归因平台中指定的活动时间范围一致。对于 SKAdNetwork 3.5,此时间可能在 1-3 天内,因此您可以按照此处列出的步骤在 Google Ads 中进行相应调整
- 如果您使用的是 Appsflyer,目前默认事件计数器为 1,这意味着它不会统计每位用户的多次事件。如果您使用基于事件的模型衡量 SKAN 效果,并与 Google Ads 上的目标每次转化费用广告系列进行比较,则可以选择按照 Appsflyer 的此指南进行自定义
5. 恭喜
恭喜,您已成功设置 SKAd Network 转化价值架构。现在,您可以监控 Google Ads SKAdNetwork 报告中的数据,以便在该报告发布后查看 Google Ads 广告系列的转化价值
您学到的内容
- 如何在 BigQuery 中探索 GA4F 中的丰富原始数据
- 一种分析方法,用于计算您的业务收入范围
- 使用 AppsFlyer 部署架构