diff --git a/examples/audience/Assets/SampleApp/Scripts/AudienceSample.cs b/examples/audience/Assets/SampleApp/Scripts/AudienceSample.cs index 211a04f5b..e6fbe99a7 100644 --- a/examples/audience/Assets/SampleApp/Scripts/AudienceSample.cs +++ b/examples/audience/Assets/SampleApp/Scripts/AudienceSample.cs @@ -189,7 +189,7 @@ private void OnIdentify() => RunAndLog("identify()", () => { var f = CaptureIdentifyForm(); var traits = ParseTraits(f.RawTraits); - ImmutableAudience.Identify(f.Id, f.Type, traits); + ImmutableAudience.Identify(f.Id, ParseIdentityType(f.Type), traits); // SDK drops via Log.Warn when id is empty or consent < Full. Mirror // only when accepted — otherwise the panel would show stale state. var accepted = !string.IsNullOrEmpty(f.Id) @@ -212,7 +212,7 @@ private void OnIdentifyTraits() => RunAndLog("identify(traits)", () => if (string.IsNullOrEmpty(userId)) throw new InvalidOperationException("no active identity — call Identify first"); var traits = ParseTraits(CaptureTraitsUpdate()); if (traits == null || traits.Count == 0) throw new InvalidOperationException("traits required"); - ImmutableAudience.Identify(userId, _mirrorIdentityType ?? IdentityType.Custom.ToLowercaseString(), traits); + ImmutableAudience.Identify(userId, ParseIdentityType(_mirrorIdentityType), traits); _mirrorTraits = traits; OnSdkStateChanged(); return Json.Serialize(traits, 2); @@ -221,7 +221,7 @@ private void OnIdentifyTraits() => RunAndLog("identify(traits)", () => private void OnAlias() => RunAndLog("alias()", () => { var f = CaptureAliasForm(); - ImmutableAudience.Alias(f.FromId, f.FromType, f.ToId, f.ToType); + ImmutableAudience.Alias(f.FromId, ParseIdentityType(f.FromType), f.ToId, ParseIdentityType(f.ToType)); // SDK drops via Log.Warn when fromId/toId is empty or consent < Full. // The IsAliasReady gate keeps empty endpoints unreachable from the // UI; this post-call check is defense-in-depth. @@ -371,5 +371,20 @@ private void ResetIdentityMirror() private static Dictionary? ParseTraits(string? raw) => string.IsNullOrWhiteSpace(raw) ? null : JsonReader.DeserializeObject(raw!); + + // Parses a wire-format identity string (e.g. "steam") back into the + // IdentityType enum the SDK now requires. Falls back to Custom for + // unknown or empty values. + private static IdentityType ParseIdentityType(string? value) => (value ?? "").ToLowerInvariant() switch + { + "passport" => IdentityType.Passport, + "steam" => IdentityType.Steam, + "epic" => IdentityType.Epic, + "google" => IdentityType.Google, + "apple" => IdentityType.Apple, + "discord" => IdentityType.Discord, + "email" => IdentityType.Email, + _ => IdentityType.Custom, + }; } } diff --git a/src/Packages/Audience/Runtime/ImmutableAudience.cs b/src/Packages/Audience/Runtime/ImmutableAudience.cs index 4a98a993e..19da33eba 100644 --- a/src/Packages/Audience/Runtime/ImmutableAudience.cs +++ b/src/Packages/Audience/Runtime/ImmutableAudience.cs @@ -308,20 +308,7 @@ public static void Track(string eventName, Dictionary? propertie /// The player's identifier within the chosen provider. /// The identity provider that issued . /// Optional player attributes (email, name, etc.). - public static void Identify(string userId, IdentityType identityType, Dictionary? traits = null) => - Identify(userId, identityType.ToLowercaseString(), traits); - - /// - /// Attaches a known user ID to subsequent events. String overload - /// for providers outside the enum. - /// - /// The player's identifier within the chosen provider. - /// - /// The identity provider name. Required. Data-deletion requests - /// match events by this namespace. - /// - /// Optional player attributes (email, name, etc.). - public static void Identify(string userId, string identityType, Dictionary? traits = null) + public static void Identify(string userId, IdentityType identityType, Dictionary? traits = null) { if (!_initialized) return; @@ -352,8 +339,8 @@ public static void Identify(string userId, string identityType, DictionaryIdentity provider for . /// The new identifier. /// Identity provider for . - public static void Alias(string fromId, IdentityType fromType, string toId, IdentityType toType) => - Alias(fromId, fromType.ToLowercaseString(), toId, toType.ToLowercaseString()); - - /// - /// Links two user IDs for the same player. String overload for - /// providers outside the enum. - /// - /// The previously-known identifier. - /// - /// Identity provider for . Required. - /// Data-deletion requests match events by this namespace. - /// - /// The new identifier. - /// - /// Identity provider for . Required. - /// - public static void Alias(string fromId, string fromType, string toId, string toType) + public static void Alias(string fromId, IdentityType fromType, string toId, IdentityType toType) { if (!_initialized) return; @@ -399,7 +370,8 @@ public static void Alias(string fromId, string fromType, string toId, string toT var config = _config; if (config == null) return; - var msg = MessageBuilder.Alias(fromId, fromType, toId, toType, config.PackageVersion); + var msg = MessageBuilder.Alias(fromId, fromType.ToLowercaseString(), toId, toType.ToLowercaseString(), + config.PackageVersion); EnqueueIdentity(msg); } diff --git a/src/Packages/Audience/Tests/Runtime/ImmutableAudienceTests.cs b/src/Packages/Audience/Tests/Runtime/ImmutableAudienceTests.cs index 6cc7e97b2..ba4f44268 100644 --- a/src/Packages/Audience/Tests/Runtime/ImmutableAudienceTests.cs +++ b/src/Packages/Audience/Tests/Runtime/ImmutableAudienceTests.cs @@ -618,7 +618,7 @@ public void Identify_FullConsent_WritesIdentifyEvent() { ImmutableAudience.Init(MakeConfig(ConsentLevel.Full)); - ImmutableAudience.Identify("76561198012345", "steam"); + ImmutableAudience.Identify("76561198012345", IdentityType.Steam); ImmutableAudience.Shutdown(); var queueDir = AudiencePaths.QueueDir(_testDir); @@ -633,7 +633,7 @@ public void Identify_AnonymousConsent_IsIgnored() { ImmutableAudience.Init(MakeConfig(ConsentLevel.Anonymous)); - ImmutableAudience.Identify("user1", "steam"); + ImmutableAudience.Identify("user1", IdentityType.Steam); ImmutableAudience.Shutdown(); var queueDir = AudiencePaths.QueueDir(_testDir); @@ -648,7 +648,7 @@ public void Alias_FullConsent_WritesAliasEvent() { ImmutableAudience.Init(MakeConfig(ConsentLevel.Full)); - ImmutableAudience.Alias("steam123", "steam", "user_456", "passport"); + ImmutableAudience.Alias("steam123", IdentityType.Steam, "user_456", IdentityType.Passport); ImmutableAudience.Shutdown(); var queueDir = AudiencePaths.QueueDir(_testDir); @@ -971,7 +971,7 @@ public void SetConsent_DowngradeToAnonymous_StressTest_NoUserIdLeak() for (int iter = 0; iter < iterations; iter++) { ImmutableAudience.Init(MakeConfig(ConsentLevel.Full)); - ImmutableAudience.Identify(testUserId, "steam"); + ImmutableAudience.Identify(testUserId, IdentityType.Steam); // Clear Init events so only race events can leak. ImmutableAudience.FlushQueueToDiskForTesting();