关于此 Codelab
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 数据集
依次前往 Project Settings > Integrations > BigQuery,前往 GA4F 中的数据集。您需要先启用此切换开关,然后大约需要 48 小时才能看到数据集。您可以点击下方显示的链接,前往 BigQuery
运行一些查询
现在,您已进入 BigQuery,应该会看到生成的每日表格。在以下示例屏幕截图中,我们看到了 64 个每日表,因此导出操作已运行 64 天。如果您是首次访问该页面,则可能只会看到 1 个包含前一天数据的每日表格。右侧显示了表架构。如需详细了解这些字段,请点击此处
如需开始编写查询,您可以依次点击查询 > 在新标签页中
然后,您可以尝试在新标签页中运行示例查询
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 Network 限制。归因时间范围只能是安装后的 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 buckets
接下来,我们将其纳入到总体查询中
#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 视为最后一个范围。这是因为应用归因服务提供商往往会使用范围的平均值来计算投资回报率 (ROAS),因此必须排除离群值,以便更均匀地进行计算。
现在,我们尝试查看所有范围内每个日期的用户数,以便了解每个存储分区中的用户每日量。我们可以使用以下示例查询来实现此目的,您可以将存储分区值替换为实际数据,查询将如下所示
#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
它应返回每天每个收入范围内的用户数,如下所示。如果您发现任何分桶中的数字非常低,或者分布普遍不均匀,则可能需要调整分桶数量并重新运行查询。
简要介绍 SKAdNetwork 4.0
SKAd Network 4.0 提供多种转化时间范围,最长可达 2 天、3-7 天和 8-35 天。在上述方法中,您还可以轻松更改时间范围,以便分析这些其他场景的数据。还提供“低”“中”和“高”这三个粗粒值。再次强调,如果您想使用这种方法,可以将其视为 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,您可以通过该工具轻松地将此 ID 直接输入界面中。您可以直接使用 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. 恭喜
恭喜!您已成功设置 SKAdNetwork 转化价值架构。现在,您可以监控 Google Ads SKAdNetwork 报告中的数据,以便在该报告发布后查看 Google Ads 广告系列的转化价值
您学到的内容
- 如何在 BigQuery 中探索 GA4F 中的丰富原始数据
- 用于计算您业务收入分桶的分析方法
- 使用 AppsFlyer 部署架构