Mobile Pushは現在ベータ版です。このドキュメントで説明されているスキーマと実装の詳細はサンプルとして提供されており、変更される可能性があります。独自のトラッキング要件とビジネスニーズに基づいて、独自のテーブルスキーマを設計してください。
Engage StudioでMobile Push通知を実装すると、モバイルアプリはユーザーインタラクションをトラッキングし、イベントデータをTreasure Dataに送信します。このデータは、Treasure Dataデータベース内の専用テーブル(推奨名: push_events)に保存されます。
このドキュメントでは、サンプルスキーマ、イベントタイプ、プッシュ通知イベントデータの操作に関するベストプラクティスについて説明します。注意: ここで提供されているスキーマはサンプルです。アプリケーションの要件とデータガバナンスポリシーに基づいてカスタマイズしてください。
以下に示すテーブル構造はサンプル実装です。以下に基づいて独自のスキーマを設計してください:
- トラッキング要件
- データガバナンスとプライバシーポリシー
- 分析とレポーティングのニーズ
- コンプライアンス要件(GDPR、CCPAなど)
| カラム名 | データ型 | 必須 | 説明 |
|---|---|---|---|
time | INTEGER | はい | イベント発生時のUnixタイムスタンプ(秒) |
type | STRING | はい | イベントタイプ: delivery, open, dismiss, link_open, deeplink_open, token_register |
td_td_campaign_id | STRING | はい | Engage Studioからのキャンペーン識別子(通知ペイロードから渡される) |
platform | STRING | はい | モバイルプラットフォーム: android または ios |
fcm_token | STRING | いいえ | Firebase Cloud Messagingデバイストークン(token_registerイベントに必須) |
user_id | STRING | いいえ | ユーザーがログインしている場合のユーザー識別子(例: 顧客ID、メールハッシュ値) |
value | STRING | いいえ | 追加データ(例: link_openまたはdeeplink_openのURL) |
device_model | STRING | いいえ | デバイスモデル(オプション拡張) |
os_version | STRING | いいえ | オペレーティングシステムバージョン(オプション拡張) |
app_version | STRING | いいえ | アプリケーションバージョン(オプション拡張) |
-- サンプルpush_eventsテーブル作成(ニーズに合わせてカスタマイズしてください)
CREATE TABLE IF NOT EXISTS mobile.push_events (
time INTEGER,
type STRING,
td_td_campaign_id STRING,
platform STRING,
fcm_token STRING,
user_id STRING,
value STRING,
device_model STRING,
os_version STRING,
app_version STRING
)プッシュ通知が正常に配信され、ユーザーに表示されたときにログに記録されます。
イベントタイプ: delivery
サンプルイベント:
{
"time": 1734134400,
"type": "delivery",
"td_campaign_id": "cmp_20251214_promo",
"platform": "android",
"user_id": "user_12345"
}トラッキングタイミング:
- Android:
MyFirebaseMessagingServiceでonMessageReceived()が呼ばれたとき - iOS:
UNUserNotificationCenterDelegateでwillPresent notificationが呼ばれたとき
ユーザーが通知をタップしてアプリを開いたときにログに記録されます。
イベントタイプ: open
サンプルイベント:
{
"time": 1734134410,
"type": "open",
"td_campaign_id": "cmp_20251214_promo",
"platform": "ios",
"user_id": "user_12345"
}トラッキングタイミング:
- Android: 通知がタップされ、
MainActivityがPushAction.OPENインテントを受信したとき - iOS:
didReceive responseがUNNotificationDefaultActionIdentifierで呼ばれたとき
ユーザーが通知を開かずに削除(スワイプ)したときにログに記録されます。
イベントタイプ: dismiss
サンプルイベント:
{
"time": 1734134420,
"type": "dismiss",
"td_campaign_id": "cmp_20251214_promo",
"platform": "android",
"user_id": "user_12345"
}トラッキングタイミング:
- Android: 通知で
deleteIntentがトリガーされたとき - iOS:
didReceive responseがUNNotificationDismissActionIdentifierで呼ばれたとき
ユーザーが通知からWebリンクをタップしたときにログに記録されます。
イベントタイプ: link_open
サンプルイベント:
{
"time": 1734134430,
"type": "link_open",
"td_campaign_id": "cmp_20251214_promo",
"platform": "android",
"user_id": "user_12345",
"value": "https://example.com/promo?utm_campaign=promo"
}トラッキングタイミング:
- Android:
PushAction.ACTION_LINKのアクションボタンがタップされたとき - iOS: 識別子
ACTION_OPEN_LINKのアクションボタンがタップされたとき
注意: valueフィールドには開かれた完全なURLが含まれます。
ユーザーが通知からアプリディープリンクをタップしたときにログに記録されます。
イベントタイプ: deeplink_open
サンプルイベント:
{
"time": 1734134440,
"type": "deeplink_open",
"td_campaign_id": "cmp_20251214_promo",
"platform": "ios",
"user_id": "user_12345",
"value": "myapp://product/12345"
}トラッキングタイミング:
- Android:
PushAction.ACTION_DEEPLINKのアクションボタンがタップされたとき - iOS: 識別子
ACTION_OPEN_DEEPLINKのアクションボタンがタップされたとき
注意: valueフィールドにはディープリンクURIが含まれます。
アプリがFCMデバイストークンをTreasure Dataに登録または更新したときにログに記録されます。
イベントタイプ: token_register
サンプルイベント:
{
"time": 1734134400,
"type": "token_register",
"fcm_token": "dQw4w9WgXcQ:APA91bF...",
"platform": "android",
"user_id": "user_12345",
"app_version": "1.2.3",
"os_version": "14",
"device_model": "Pixel 7"
}トラッキングタイミング:
- Android:
MyFirebaseMessagingServiceでonNewToken()が呼ばれたとき - iOS:
MessagingDelegateでdidReceiveRegistrationTokenが呼ばれたとき - トークンが最新であることを確認するため、アプリ起動時にもトリガーされます
注意:
- ログイン済みユーザーの場合、
user_idを含める必要があります - 匿名ユーザーの場合、
user_idはnullにできます — ユーザーがログイン後に関連付けられます
token_registerイベントは、デバイストークンをユーザーIDにリンクするために重要です。関連付けの仕組みは次のとおりです:
ユーザーがアプリをインストールし、既にログインしている(またはすぐにログインする)場合:
{
"type": "token_register",
"fcm_token": "ABC123...",
"user_id": "user_12345",
"platform": "android"
}トークンは即座にユーザーに関連付けられます。
ユーザーがアプリをインストールしたが、まだログインしていない場合:
{
"type": "token_register",
"fcm_token": "ABC123...",
"user_id": null,
"platform": "android"
}トークンは登録されますが、まだユーザーにリンクされていません。
以前は匿名だったユーザーがログインした場合、新しいtoken_registerイベントを送信します:
{
"type": "token_register",
"fcm_token": "ABC123...",
"user_id": "user_12345",
"platform": "android"
}Treasure Dataは、このfcm_tokenを持つすべての過去のイベントをuser_12345にリンクできるようになります。
匿名トークンをユーザーに解決するには、次のクエリを使用します:
WITH latest_tokens AS (
SELECT
fcm_token,
user_id,
time,
ROW_NUMBER() OVER (PARTITION BY fcm_token ORDER BY time DESC) AS rn
FROM mobile.push_events
WHERE type = 'token_register'
AND user_id IS NOT NULL
)
SELECT
fcm_token,
user_id
FROM latest_tokens
WHERE rn = 1すべてのキャンペーンの配信率、開封率、クリック率を取得:
SELECT
td_campaign_id,
COUNT(CASE WHEN type = 'delivery' THEN 1 END) AS deliveries,
COUNT(CASE WHEN type = 'open' THEN 1 END) AS opens,
COUNT(CASE WHEN type = 'link_open' OR type = 'deeplink_open' THEN 1 END) AS clicks,
COUNT(CASE WHEN type = 'dismiss' THEN 1 END) AS dismissals,
ROUND(100.0 * COUNT(CASE WHEN type = 'open' THEN 1 END) / NULLIF(COUNT(CASE WHEN type = 'delivery' THEN 1 END), 0), 2) AS open_rate_pct,
ROUND(100.0 * COUNT(CASE WHEN type = 'link_open' OR type = 'deeplink_open' THEN 1 END) / NULLIF(COUNT(CASE WHEN type = 'delivery' THEN 1 END), 0), 2) AS click_rate_pct
FROM mobile.push_events
WHERE time >= CAST(strftime('%s', 'now', '-30 days') AS INTEGER)
GROUP BY td_campaign_id
ORDER BY deliveries DESCAndroidとiOSのパフォーマンスを比較:
SELECT
platform,
COUNT(CASE WHEN type = 'delivery' THEN 1 END) AS deliveries,
COUNT(CASE WHEN type = 'open' THEN 1 END) AS opens,
ROUND(100.0 * COUNT(CASE WHEN type = 'open' THEN 1 END) / NULLIF(COUNT(CASE WHEN type = 'delivery' THEN 1 END), 0), 2) AS open_rate_pct
FROM mobile.push_events
WHERE td_campaign_id = 'cmp_20251214_promo'
GROUP BY platformユーザーが通知を開くまでの時間を分析:
WITH delivery_times AS (
SELECT
td_campaign_id,
user_id,
fcm_token,
time AS delivery_time
FROM mobile.push_events
WHERE type = 'delivery'
),
open_times AS (
SELECT
td_campaign_id,
user_id,
fcm_token,
time AS open_time
FROM mobile.push_events
WHERE type = 'open'
)
SELECT
CASE
WHEN (o.open_time - d.delivery_time) < 60 THEN '< 1 minute'
WHEN (o.open_time - d.delivery_time) < 300 THEN '1-5 minutes'
WHEN (o.open_time - d.delivery_time) < 3600 THEN '5-60 minutes'
WHEN (o.open_time - d.delivery_time) < 86400 THEN '1-24 hours'
ELSE '> 24 hours'
END AS time_bucket,
COUNT(*) AS count
FROM delivery_times d
JOIN open_times o
ON d.td_campaign_id = o.td_campaign_id
AND d.user_id = o.user_id
AND d.fcm_token = o.fcm_token
GROUP BY time_bucket
ORDER BY MIN(o.open_time - d.delivery_time)最も多くクリックされたリンクを特定:
SELECT
td_campaign_id,
value AS clicked_url,
COUNT(*) AS click_count,
COUNT(DISTINCT user_id) AS unique_users
FROM mobile.push_events
WHERE type IN ('link_open', 'deeplink_open')
AND value IS NOT NULL
GROUP BY td_campaign_id, value
ORDER BY click_count DESC
LIMIT 20デイリーアクティブデバイストークンをトラッキング:
SELECT
DATE(time, 'unixepoch') AS event_date,
platform,
COUNT(DISTINCT fcm_token) AS active_tokens
FROM mobile.push_events
WHERE time >= CAST(strftime('%s', 'now', '-30 days') AS INTEGER)
AND type IN ('delivery', 'open', 'link_open', 'deeplink_open')
GROUP BY event_date, platform
ORDER BY event_date DESC, platform特定のキャンペーンのエンゲージメントファネルを分析:
WITH funnel_data AS (
SELECT
user_id,
MAX(CASE WHEN type = 'delivery' THEN 1 ELSE 0 END) AS delivered,
MAX(CASE WHEN type = 'open' THEN 1 ELSE 0 END) AS opened,
MAX(CASE WHEN type IN ('link_open', 'deeplink_open') THEN 1 ELSE 0 END) AS clicked
FROM mobile.push_events
WHERE td_campaign_id = 'cmp_20251214_promo'
GROUP BY user_id
)
SELECT
SUM(delivered) AS total_delivered,
SUM(opened) AS total_opened,
SUM(clicked) AS total_clicked,
ROUND(100.0 * SUM(opened) / NULLIF(SUM(delivered), 0), 2) AS open_rate_pct,
ROUND(100.0 * SUM(clicked) / NULLIF(SUM(opened), 0), 2) AS click_through_rate_pct
FROM funnel_data大規模デプロイメントでは、日付別にテーブルをパーティション化することを検討してください:
-- 月次パーティションテーブルを作成
CREATE TABLE mobile.push_events_202512 AS
SELECT * FROM mobile.push_events
WHERE time >= 1733011200 AND time < 173568960090日以上前のイベントを別のテーブルにアーカイブ:
CREATE TABLE mobile.push_events_archive AS
SELECT * FROM mobile.push_events
WHERE time < CAST(strftime('%s', 'now', '-90 days') AS INTEGER)メインテーブルから削除:
DELETE FROM mobile.push_events
WHERE time < CAST(strftime('%s', 'now', '-90 days') AS INTEGER)推奨: プッシュ通知イベントを別のpush_eventsテーブルに保存します。
理由: プッシュイベントは一般的なアプリイベント(例: event_app)とは異なるスキーマを持つため、クエリと分析が容易になります。
ユーザーがログインしている場合は、常にイベントにuser_idを含めてください。これにより次のことが可能になります:
- ユーザーレベルの分析
- クロスデバイストラッキング
- パーソナライズされたキャンペーン最適化
イベントをバッチ(リクエストあたり最大500イベント)でアップロードして:
- ネットワークオーバーヘッドを削減
- アプリパフォーマンスを向上
- ネットワーク状態が悪い場合でも確実な配信を保証
イベントアップロードが失敗した場合:
- イベントをローカルキューに保持
- 指数バックオフでリトライ
- 最大リトライ試行回数を制限(例: 3〜5回)
定期的に次のことを確認:
- 必須フィールドの欠落(
td_campaign_id、platform、type) - 重複イベント(同じ
td_campaign_id+user_id+fcm_token+type+time) - 異常なイベントパターン(例: 配信なしの開封)
ビジネスに関連する追加フィールドでスキーマを拡張:
device_model: デバイスタイプ別のパフォーマンストラッキングos_version: OS固有の問題の特定app_version: イベントとアプリリリースの関連付けlocation: 地理ベースの分析(プライバシーコンプライアンスを確保)
- PIIをログに記録しない: イベントにメールアドレス、電話番号、その他の個人を特定できる情報を保存しないでください
- ユーザーIDをハッシュ化: Treasure Dataに送信する前にユーザーIDのハッシュ化を検討してください
- 書き込み専用キーを使用: モバイルアプリは書き込み専用APIキーを使用し、マスターキーは絶対に使用しないでください
- 転送中の暗号化: すべてのデータアップロードはHTTPSを使用します
アプリがプライバシー規制地域のユーザーにサービスを提供する場合:
- イベントをトラッキングする前にユーザーの同意を取得
- オプトアウトメカニズムを提供
- データ削除ワークフローを実装
- データ保持ポリシーを文書化
- Mobile Pushセットアップ - FirebaseとTreasure Data統合の設定
- Android開発者ガイド - Androidでプッシュ通知を実装
- iOS開発者ガイド - iOSでプッシュ通知を実装
- キャンペーン作成 - Mobile Pushキャンペーンの作成と送信