跳到主要内容

Unity 消息推送集成文档

最近更新 2026/10/07

一、FCM推送​

1.1 上报 "推送 ID"​

  • 在调用 AE Login 或者切换账号之后上传 FCM 的 Token。
//AE SDK 初始化
TDAnalytics.Init("APPID", "SERVER");
//设置账号 ID
TDAnalytics.Login("ACCOUNT_ID");
//上报 FCM token 到 AE 系统
Firebase.Messaging.FirebaseMessaging.GetTokenAsync().ContinueWith(task => {
var result = task.Result;
//需要切换到主线程去上报 UnityMainThreadDispatcher可以参考附录
UnityMainThreadDispatcher.Instance.Enqueue(() =>
{
//上报 FCM token 到 AE 系统
TDAnalytics.UserSet(new Dictionary<string, object>() {
{ "fcm_token", task.Result }
});
});
});
  • 在 FCM Token 变更时,更新用户属性:
private void Start()
{
// 注册 FCM Token 更新委托事件
Firebase.Messaging.FirebaseMessaging.TokenReceived += OnTokenReceived;
Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
}

public void OnTokenReceived(object sender, Firebase.Messaging.TokenReceivedEventArgs token)
{
//上报 FCM token 到 AE 系统
TDAnalytics.UserSet(new Dictionary<string, object>() {
{ "fcm_token", token.Token }
});
}

1.2 采集推送点击事件​

在用户点击通知时上传推送点击事件,可以在 FCM 的 OnMessageReceived 回调中获取推送参数。

private void Start()
{
// 注册 FCM 消息委托事件
Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
}

public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)
{
// 推送事件上报 (TETrackMessageReceived参见附录)
if (e.Message.Data.ContainsKey("te_extras"))
{
this.TETrackMessageReceived(e.Message.Data);
}
}

1.3 处理推送消息​

建议以下两种方案二选一。

  • 普通参数:调用TEHandlePushAction方法。
  • 透传参数:调用TEHandlePassThroughAction方法。
private void Start()
{
// 注册 FCM 消息委托事件
Firebase.Messaging.FirebaseMessaging.MessageReceived += OnMessageReceived;
}

public void OnMessageReceived(object sender, Firebase.Messaging.MessageReceivedEventArgs e)
{
//如果处理普通参数 调用如下方法 (TEHandlePushAction参见附录)
this.TEHandlePushAction(e.Message.Data);
//如果处理透传参数 调用如下方法
this.TEHandlePassThroughAction(e.Message.Data);
}

二、极光推送​

提示

极光推送官网暂未提供 Unity 插件,可以参考极光维护的开源插件:JPush Unity Plugin。以下内容均在 JPush Unity Plugin 基础上实现。

2.1 上报 "推送 ID"​

  • 在调用 AE Login 或者切换账号之后上传极光的 Registration ID。
//AE SDK 初始化
TDAnalytics.Init("APPID", "SERVER");
//设置账号 ID
TDAnalytics.Login("ACCOUNT_ID");
//上报 JPush Registration ID 到 AE 系统
string jiguangId = JPushBinding.GetRegistrationId();
TDAnalytics.UserSet(new Dictionary<string, object>() {
{ "jiguang_id", jiguangId }
});
  • 在极光的 OnGetRegistrationId 接口中上传极光的 Registration ID。
void OnGetRegistrationId(string result)
{
//上报 JPush Registration ID 到 AE 系统
TDAnalytics.UserSet(new Dictionary<string, object>() {
{ "jiguang_id", result }
});
}

2.2 采集推送点击事件​

void OnOpenNotification(string jsonStr)
{
IDictionary<string, object> json = ThinkingData.Analytics.Utils.TDMiniJson.Deserialize(jsonStr);
if (json.ContainsKey("te_extras"))
{
object v = json["te_extras"];
this.TETrackMessageReceived((IDictionary<string, string>)v);
}
}

2.3 处理推送消息​

建议以下两种方案二选一。

  • 普通参数:调用TEHandlePushAction方法。
  • 透传参数:调用TEHandlePassThroughAction方法。
void OnOpenNotification(string jsonStr)
{
Debug.Log("recv---openNotification---" + jsonStr);
IDictionary<string, object> json = ThinkingData.Analytics.Utils.TDMiniJson.Deserialize(jsonStr);
if (json.ContainsKey("extras"))
{
object v = json["extras"];
//如果处理普通参数 调用如下方法
this.TEHandlePushAction((IDictionary<string, string>)v);
//如果处理透传参数 调用如下方法
this.TEHandlePassThroughAction((IDictionary<string, string>)v);
}
}

附录​

客户端收到推送参数示例​

以下仅展示客户端收到的扩展字段参数

{
"te_extras": {
//点击推送的跳转方式
"ops_loading_type": "OPEN_APP",
//透传参数
"passthrough_params": {
"param1": "abc",
"param2": 101,
"param3": [{
"subText1": "xyz",
"subText2": 2
}]
},
//AE运营通道回执属性
"#ops_receipt_properties": {
"ops_task_id": "0082",
"ops_project_id": 1,
"ops_task_instance_id": "0082_20230331",
"ops_push_language": "default",
"ops_task_exec_detail_id": "55"
}
}
}

TETrackMessageReceived​

private void TETrackMessageReceived(IDictionary<string, string> data)
{
//上报 FCM message 事件到 AE 系统
Dictionary<string, object> te_extras = ThinkingData.Analytics.Utils.TDMiniJson.Deserialize(data["te_extras"]);
Dictionary<string, object> properties = new Dictionary<string, object>();
if (te_extras.ContainsKey("#ops_receipt_properties"))
{
properties.Add("#ops_receipt_properties", te_extras["#ops_receipt_properties"]);
}
TDAnalytics.Track("te_ops_push_click", properties);
TDAnalytics.Flush();
}

TEHandlePushAction​

private void TEHandlePushAction(IDictionary<string, string> data)
{
Dictionary<string, object> te_extras = ThinkingData.Analytics.Utils.TDMiniJson.Deserialize(data["te_extras"]);
string type = te_extras["ops_loading_type"].ToString();
if ("OPEN_APP".Equals(type))
{
// 处理打开 App 消息,--> 请启动 App
}
else if ("OPEN_URL".Equals(type))
{
string url = te_extras["ops_url"].ToString();
if (!string.IsNullOrEmpty(url))
{
// 处理打开 URL 消息,--> 请处理 URL
}
}
else if ("CUSTOMIZED".Equals(type))
{
string custom = te_extras["ops_customized"].ToString();
if (!string.IsNullOrEmpty(custom))
{
// 处理自定义消息,--> 请处理自定义消息
}
}
}

TEHandlePassThroughAction​

private void TEHandlePassThroughAction(IDictionary<string, string> data)
{
Dictionary<string, object> te_extras = ThinkingData.Analytics.Utils.TDMiniJson.Deserialize(data["te_extras"]);
string passThroughParams = te_extras["passthrough_params"].ToString();
//passThroughParams为透传参数,接下来是实现具体的业务逻辑
}

UnityMainThreadDispatcher​

public class UnityMainThreadDispatcher : MonoBehaviour
{
private static readonly Queue<Action> _executionQueue = new Queue<Action>();

public static UnityMainThreadDispatcher Instance { get; private set; }

private void Awake()
{
if (Instance == null)
{
Instance = this;
DontDestroyOnLoad(this.gameObject);
}
else
{
Destroy(gameObject);
}
}

public void Update()
{
lock (_executionQueue)
{
while (_executionQueue.Count > 0)
{
_executionQueue.Dequeue().Invoke();
}
}
}

public void Enqueue(IEnumerator action)
{
lock (_executionQueue)
{
_executionQueue.Enqueue(() => { StartCoroutine(action); });
}
}

public void Enqueue(Action action)
{
Enqueue(ActionWrapper(action));
}

IEnumerator ActionWrapper(Action a)
{
a();
yield return null;
}
}
这篇文档对你有帮助吗?