fix: [SDK-4523] Unity custom event nested property encoding#871
Merged
Conversation
nan-li
approved these changes
May 18, 2026
75a01c2 to
5ea0ca2
Compare
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
One Line Summary
Fix Unity custom event properties losing nested objects/typed arrays on the way to the dashboard, plus add the GitHub Actions E2E workflow that runs the Appium suite against the demo app.
Details
Motivation
Linear: SDK-4523 Unity Custom Events.
OneSignal.User.TrackEvent(name, properties)on Unity was mangling complex property values on both Android and iOS. Given:{ "someNum": 123, "someFloat": 3.14159, "someObject": { "abc": "123", "nested": { "def": "456" }, "ghi": null }, "someArray": [1, 2], "someMixedArray": [1, "2", { "abc": "123" }, null] }the dashboard received:
{ "someArray": ["1", "2"], "someObject": [null, null, null], "someMixedArray": ["1", "2", null, ""] }Two root causes:
com.onesignal.unity.core/Runtime/Utilities/MiniJSON.cs) checkedIListbeforeIDictionary. Any dict-like type that also implementsIList(Newtonsoft'sJObjectis the common case, sinceJContainer : IList<JToken>) was serialized as a JSON array of its childJPropertyitems, producing[null, null, null]for a 3-key object.ToMap(com.onesignal.unity.android/Runtime/Utilities/AndroidJavaObjectExtensions.cs) switched on the concrete typeDictionary<string, object>only.JObjectis notDictionary<string, object>, so it fell into theIListcase and was treated as a JSON array.Demo on top of that used
Newtonsoft.JsonConvert.DeserializeObject<Dictionary<string, object>>, which is exactly the path that surfacesJObject/JArraywrappers.Scope
int,double) property encoding forOneSignal.User.TrackEventon iOS and Android.Dictionary<string, object>/List<object>continue to work as before.run-android.sh/run-ios.shnow auto-detect Unity (newest6000.xunder the Hub) andadb(ANDROID_HOME,~/Library/Android/sdk,which adb, then Unity's bundled SDK) instead of hardcoding a specific editor version.Changes by file
com.onesignal.unity.core/Runtime/Utilities/MiniJSON.csIDictionarybeforeIListinSerializeValuecom.onesignal.unity.android/Runtime/Utilities/AndroidJavaObjectExtensions.csToMapmatchesIDictionarybeforeIList(replaces strictDictionary<string, object>)examples/demo/Assets/Scripts/UI/Dialogs/TrackEventDialog.csDictionary<string, object>/List<object>) instead of Newtonsoft, which returnsJObject/JArrayexamples/demo/run-android.sh,run-ios.sh.github/workflows/e2e.yml,.github/actions/create-demo-env/action.yml,examples/demo/Assets/Scripts/Editor/BuildScript.cs.envactionTesting
Manual testing
TEST_JSON(seeappium/tests/specs/10_event.spec.ts) on Android emulator (Pixel 6, API 34) and iOS Simulator (iPhone 16 Pro, iOS 26.2). Verified on the OneSignal dashboard thatsomeObjectis a nested object,someArraycontains numbers (not strings), andsomeMixedArraypreserves its inner object/null entries../run-android.shand./run-ios.shwith noUNITY_PATH/ADBset and confirmed they discover the newest installed Unity6000.xand~/Library/Android/sdk/platform-tools/adb.Made temp changes to custom events section e.g.
to test props_native vs just the json parsing.
Unit / E2E
appium/tests/specs/10_event.spec.tsexercisestrack_event_buttonwith this JSON. The E2E workflow added in this PR will run that spec against the demo on every PR going forward.Affected code checklist
Checklist
Overview
Testing
Final pass