虚幻引擎 SDK - 卸载跟踪

文档

卸载跟踪

通过将推送通知服务与 Singular SDK 集成,跟踪应用程序的卸载情况,以衡量用户保留率并优化重新参与活动。

重要:谷歌已于 2018 年 4 月弃用 GCM API。 所有安卓卸载跟踪实施均使用 Firebase Cloud Messaging (FCM)。

安卓卸载跟踪

前提条件

在您的虚幻引擎应用程序中实施卸载跟踪之前,请按照设置 Android 卸载跟踪指南在 Singular 平台中配置您的应用程序。


系统要求

卸载跟踪需要 Firebase Cloud Messaging 和特定的设备配置。

FCM 要求(源代码):

  • 安卓版本:设备必须运行 Android 4.1 (API 16) 或更高版本
  • Google Play 服务:设备必须安装 Google Play Store 应用程序
  • 模拟器支持:支持带有 Google API 的 Android 4.1 或更高版本模拟器
  • 分发:应用程序可在 Google Play Store 之外分发,同时仍支持卸载跟踪

注意:不支持的 Android 版本或没有 Google Play 服务的设备上的用户将不会被跟踪卸载。


实施步骤

第 1 步:整合 Firebase 云消息服务

在您的虚幻引擎应用程序中设置Firebase云消息(如果尚未配置)。

请按照Google的官方指南在Android上设置Firebase云消息客户端应用程序。 这包括:

  1. 将Firebase添加到您的安卓项目中
  2. 将Firebase Messaging依赖关系添加到您的build.gradle文件中
  3. 在 google-services.json 中配置 Firebase 设置
  4. 请求通知权限(Android 13+)

第 2 步:配置 AndroidManifest.xml

在 Android 清单中注册 Firebase 消息服务,以接收 FCM 消息。

AndroidManifest.xml
<service 
    android:name=".java.MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

重要:.java.MyFirebaseMessagingService 替换为扩展FirebaseMessagingService 的类的完整限定名称。


步骤 3:注册 FCM 设备令牌

读取FCM设备令牌,并将其发送至Singular,以便使用SetUninstallToken 方法进行卸载跟踪。

C++
// After initializing Singular SDK, register the FCM token
void AYourGameMode::RegisterFCMToken()
{
    // Get FCM token from Firebase Messaging
    // This assumes you have Firebase integrated and can retrieve the token
    FString FCMToken = GetFirebaseCloudMessagingToken();

    if (!FCMToken.IsEmpty())
    {
        // Register token with Singular
        USingularSDKBPLibrary::SetUninstallToken(FCMToken);
        UE_LOG(LogTemp, Log, TEXT("FCM token registered with Singular: %s"), *FCMToken);
    }
    else
    {
        UE_LOG(LogTemp, Warning, TEXT("FCM token is empty"));
    }
}

// Example helper method to get FCM token (platform-specific implementation required)
FString AYourGameMode::GetFirebaseCloudMessagingToken()
{
    FString Token;

    #if PLATFORM_ANDROID
    // Use JNI to call Firebase Messaging getToken() method
    // This requires platform-specific code to access Firebase SDK
    if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
    {
        // Implement JNI call to Firebase Messaging getToken()
        // Example: Token = CallFirebaseGetToken(Env);
        UE_LOG(LogTemp, Log, TEXT("Retrieving FCM token via JNI"));
    }
    #endif

    return Token;
}

方法签名

static void SetUninstallToken(FString token);

参数

  • token:字符串形式的 FCM 设备令牌

注意: SetUninstallToken 方法应在 Singular SDK 初始化后调用。FCM 令牌可在 SDK 初始化后的任何时间注册。


步骤 4:处理令牌刷新

每当刷新FCM令牌时,就用Singular更新令牌,以保持准确的卸载跟踪。

C++
// Handle FCM token refresh
void AYourGameMode::OnFCMTokenRefresh(const FString& NewToken)
{
    UE_LOG(LogTemp, Log, TEXT("FCM token refreshed: %s"), *NewToken);

    // Update token with Singular
    USingularSDKBPLibrary::SetUninstallToken(NewToken);

    // Also send token to your server if needed
    SendTokenToServer(NewToken);
}

void AYourGameMode::SendTokenToServer(const FString& Token)
{
    // Implement your server communication logic here
    UE_LOG(LogTemp, Log, TEXT("Sending token to server: %s"), *Token);
}

最佳实践:FCM 令牌可以随时刷新(应用程序更新、设备还原等)。请始终处理令牌刷新事件,以便用最新令牌更新 Singular。


iOS 卸载跟踪

前提条件

iOS 卸载跟踪基于苹果推送通知服务(APN)技术。

如果您的应用程序不支持推送通知,请参阅 Apple向 APNs 注册应用程序的指南


注册 APNs 设备令牌

在 SDK 初始化后,使用SetUninstallToken 方法传递从 APNs 返回的设备令牌。

方法签名

static void SetUninstallToken(FString token);

参数

  • token:从 APNs 返回的设备令牌,十六进制字符串

令牌格式:APNs 令牌的原始格式通常是二进制数据,但必须以十六进制字符串的形式传递给 Singular。


使用示例

向 Singular 注册 APNs 设备令牌,用于 iOS 卸载跟踪。

C++
// Register APNs token with Singular
void AYourGameMode::RegisterAPNsToken()
{
    #if PLATFORM_IOS
    // Get APNs device token (platform-specific implementation required)
    FString APNsToken = GetAPNsDeviceToken();

    if (!APNsToken.IsEmpty())
    {
        // Pass the token as a hex-string to Singular
        USingularSDKBPLibrary::SetUninstallToken(APNsToken);
        UE_LOG(LogTemp, Log, TEXT("APNs token registered: %s"), *APNsToken);
    }
    else
    {
        UE_LOG(LogTemp, Warning, TEXT("Failed to get APNs device token"));
    }
    #endif
}

// Example helper method to get APNs token (platform-specific implementation required)
FString AYourGameMode::GetAPNsDeviceToken()
{
    FString Token;

    #if PLATFORM_IOS
    // Use Objective-C++ to access APNs token
    // This requires platform-specific code in a .mm file
    // Example: Token = GetIOSDeviceToken();
    UE_LOG(LogTemp, Log, TEXT("Retrieving APNs token"));
    #endif

    return Token;
}

令牌示例

// Pass the APNs token as a hex-string
USingularSDKBPLibrary::SetUninstallToken(TEXT("ba85ab31a7c7f5c2f012587f29fb0e596d4b67e7b7b2838fa1a8582c1f7dbdee"));

平台一致性: SetUninstallToken 方法对 Android(FCM)和 iOS(APNs)的作用相同。在两个平台上都要在 SDK 初始化后调用该方法。


特定平台令牌检索

通过 JNI 获取安卓 FCM 令牌

在虚幻引擎中使用 JNI(Java 本地接口)访问 Firebase 云消息令牌。

C++
#if PLATFORM_ANDROID
#include "Android/AndroidJNI.h"
#include "Android/AndroidApplication.h"

FString AYourGameMode::GetFirebaseCloudMessagingToken()
{
    FString Token;

    if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
    {
        // Get FirebaseMessaging class
        jclass FirebaseMessagingClass = FAndroidApplication::FindJavaClass(
            "com/google/firebase/messaging/FirebaseMessaging"
        );

        if (FirebaseMessagingClass != nullptr)
        {
            // Get getInstance() method
            jmethodID GetInstanceMethod = Env->GetStaticMethodID(
                FirebaseMessagingClass,
                "getInstance",
                "()Lcom/google/firebase/messaging/FirebaseMessaging;"
            );

            // Call getInstance()
            jobject FirebaseMessagingInstance = Env->CallStaticObjectMethod(
                FirebaseMessagingClass,
                GetInstanceMethod
            );

            if (FirebaseMessagingInstance != nullptr)
            {
                // Get getToken() method
                jmethodID GetTokenMethod = Env->GetMethodID(
                    FirebaseMessagingClass,
                    "getToken",
                    "()Lcom/google/android/gms/tasks/Task;"
                );

                // Note: getToken() returns a Task, so you need to implement
                // async handling or use addOnCompleteListener
                // This is a simplified example - production code requires
                // proper Task handling

                UE_LOG(LogTemp, Log, TEXT("FCM token retrieval initiated"));
            }

            Env->DeleteLocalRef(FirebaseMessagingClass);
        }
    }

    return Token;
}
#endif

实现注意事项:Firebase 的getToken()返回一个异步解析的任务对象。生产实现应使用带有完成监听器的 Firebase 任务 API 来正确检索令牌。


通过 Objective-C++ 获取 iOS APN 令牌

在虚幻引擎中使用 Objective-C++ 访问 Apple Push Notification 服务令牌。

实现方法:在您的虚幻引擎项目中创建一个单独的.mm(Objective-C++)文件,以便与iOS APNs API接口。 公开C++可调用函数,以检索设备令牌并将其转换为十六进制字符串。

Objective-C++ 实现示例(YourProject_IOS.mm)

Objective-C++
// YourProject_IOS.mm
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h>

// Convert NSData to hex string
NSString* ConvertTokenToHexString(NSData* deviceToken)
{
    const unsigned char* bytes = (const unsigned char*)[deviceToken bytes];
    NSMutableString* hexString = [NSMutableString string];

    for (NSUInteger i = 0; i < [deviceToken length]; i++)
    {
        [hexString appendFormat:@"%02x", bytes[i]];
    }

    return hexString;
}

// C++ callable function to get APNs token
extern "C" const char* GetIOSAPNsToken()
{
    UIApplication* app = [UIApplication sharedApplication];

    // Request notification authorization
    UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | 
                                             UNAuthorizationOptionSound | 
                                             UNAuthorizationOptionBadge)
                          completionHandler:^(BOOL granted, NSError* error)
    {
        if (granted)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                [app registerForRemoteNotifications];
            });
        }
    }];

    // Note: The actual token is received in application:didRegisterForRemoteNotificationsWithDeviceToken:
    // You need to implement an AppDelegate to capture this

    return nullptr; // Token is received asynchronously
}

异步实现:APN 令牌注册是异步的。实施适当的 AppDelegate 方法,以便在收到令牌时捕获令牌,然后调用SetUninstallToken


验证和故障排除

验证实施

确认卸载跟踪工作正常。

  1. 检查日志:验证令牌注册是否出现在虚幻引擎输出日志中。
  2. 测试令牌生成:确保在首次启动应用程序时生成令牌
  3. 监控仪表板:检查 Singular 仪表板,查看 24-48 小时后的卸载跟踪数据
  4. 测试令牌刷新:清除应用程序数据并验证令牌更新是否正确

常见问题

  • 未生成 Android 令牌:验证是否正确添加了 Firebase 依赖关系,是否在虚幻引擎 Android 项目中配置了 google-services.json。
  • 令牌未更新:为 FCM 和 APN 实施正确的令牌刷新处理
  • 数据缺失:确保设备满足平台要求(支持 Google Play 服务的 Android 4.1+,支持 APN 的 iOS
  • 配置错误:确认已在 Singular 平台设置中启用卸载跟踪功能
  • JNI 错误:确认 Firebase 类已正确包含在 Android 构建中,且 ProGuard 规则未剥离必要的类
  • iOS 令牌格式:确保 APNs 令牌从二进制数据正确转换为十六进制字符串格式

其他资源:有关详细的故障排除,请参阅《Android 卸载跟踪设置指南》Firebase Cloud Messaging for Android 文档


方法参考

设置卸载令牌

向 Singular 注册推送通知令牌(Android 版为 FCM,iOS 版为 APNs)以启用卸载跟踪。

属性 详细信息
说明 传递从 APNs(iOS)或 FCM(Android)返回的设备令牌。 令牌通常是本地形式的二进制数据,但你需要以字符串形式传递。
签名 static void SetUninstallToken(FString token)
参数 token:FCM 或 APNs 设备令牌字符串(APNs 为十六进制格式
平台 安卓(FCM)、iOS(APN)
时间 SDK 初始化后调用

使用示例

C++
// Android FCM token
FString FCMToken = TEXT("eXaMpLeToKeN123456789abcdef");
USingularSDKBPLibrary::SetUninstallToken(FCMToken);

// iOS APNs token (hex-string format)
FString APNsToken = TEXT("ba85ab31a7c7f5c2f012587f29fb0e596d4b67e7b7b2838fa1a8582c1f7dbdee");
USingularSDKBPLibrary::SetUninstallToken(APNsToken);