Description
New Issue Checklist
- I am not disclosing a vulnerability.
- I am not just asking a question.
- I have searched through existing issues.
- I can reproduce the issue with the latest versions of Parse Server and the Parse .NET SDK.
Issue Description
An ArgumentException and many other similar exceptions are occuring whenever building a Unity build with Parse onto a WebGL release. This exception occurs as soon as the project is run in the browser, as well as whenever I attempt to use any Parse methods, such as ParseClient.Instance.LogInAsync(string username, string password) in the browser.
Example Exception:
ArgumentException: Cannot register a type that does not implement the default constructor!
at Parse.Platform.Objects.ParseObjectClassController.AddValid (System.Type type) [0x00000] in <00000000000000000000000000000000>:0
When exceptions are set to display the full exception and stack trace in the build settings, I also get this as the first exception, but in any attempts after that (for instance, in the Update loop), I instead get a NullReferenceException.
ArgumentException:
ArgumentException: Cannot register a type that does not implement the default constructor!
at Parse.Platform.Objects.ParseObjectClassController.AddValid (System.Type type) [0x00000] in <00000000000000000000000000000000>:0
at Parse.Platform.Objects.ParseObjectClassController.AddIntrinsic () [0x00000] in <00000000000000000000000000000000>:0
at Parse.ParseClient..ctor (Parse.Abstractions.Infrastructure.IServerConnectionData configuration, Parse.Abstractions.Infrastructure.IServiceHub serviceHub, Parse.Abstractions.Infrastructure.IServiceHubMutator[] configurators) [0x00000] in <00000000000000000000000000000000>:0
at ParseClientInitializer.Awake () [0x00000] in <00000000000000000000000000000000>:0
NullReferenceException:
System.NullReferenceException: Object reference not set to an instance of an object.
at Parse.UserServiceExtensions.LogInAsync (Parse.Abstractions.Infrastructure.IServiceHub serviceHub, System.String username, System.String password, System.Threading.CancellationToken cancellationToken) [0x00000] in <00000000000000000000000000000000>:0
at ParseClientInitializer.LoginParseClient (LoginCredentials loginCreds) [0x00000] in <00000000000000000000000000000000>:0
at JavascriptHook.ReceiveLoginCredentials (System.String loginJson) [0x00000] in <00000000000000000000000000000000>:0
at JavascriptHook.Start () [0x00000] in <00000000000000000000000000000000>:0
at System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Start[TStateMachine] (TStateMachine& stateMachine) [0x00000] in <00000000000000000000000000000000>:0
at JavascriptHook.Start () [0x00000] in <00000000000000000000000000000000>:0
UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
UnityEngine.Logger:Log(LogType, Object)
UnityEngine.Debug:LogError(Object)
JavascriptHook:ReceiveLoginCredentials(String)
<Start>d__6:MoveNext()
System.Runtime.CompilerServices.AsyncVoidMethodBuilder:Start(<Start>d__6&)
JavascriptHook:Start()
Full example code:
void Awake()
{
var connectionDataClient = new ParseClient(new ServerConnectionData
{
ApplicationID = "APP_ID",
ServerURI = "http://127.0.0.1:1337/parse/",
Key = "FAKE_API_KEY",
MasterKey = "FAKE_MASTER_KEY"
},
new LateInitializedMutableServiceHub { },
new MetadataMutator
{
EnvironmentData = new EnvironmentData { OSVersion = SystemInfo.operatingSystem, Platform = $"Unity {Application.unityVersion} on {SystemInfo.operatingSystemFamily}", TimeZone = TimeZoneInfo.Local.StandardName },
HostManifestData = new HostManifestData { Name = Application.productName, Identifier = Application.productName, ShortVersion = Application.version, Version = Application.version }
},
new AbsoluteCacheLocationMutator
{
CustomAbsoluteCacheFilePath = $"{Application.persistentDataPath.Replace('/', Path.DirectorySeparatorChar)}{Path.DirectorySeparatorChar}Parse.cache"
}
);
connectionDataClient.Publicize();
}
public void LoginParseClient(string username, string password)
{
ParseClient.Instance.LogInAsync(username, password);
}
public void Start() {
LoginParseClient("myUsername", "myPassword");
}
Has anyone else encountered this issue before? Is there any workarounds, or is Unity web deployment not supported?
Steps to reproduce
- Create a unity project. Add Parse.dll to Assets/Plugins.
- Create a code file with a ParseClient initialization connecting to an existing parse server with code for logging in a user with LogInAsync.
- Observe that the code runs correctly when running on a local test.
- Set target build platform to WebGL
- Set webGL settings for maximum web compatability. Build settings --> Publishing settings --> Turn on stack traces, set compression to Gzip, turn on compression fallback
- Build and run
Actual Outcome
When loading in files that use code from ParseInfrastructure, it causes an ArgumentException on startup. From then on, any uses of the code cause a NullReferenceException. The errors and stack traces are seen above.
Expected Outcome
The code should simply log in the user.
Environment
Unity 2022.3.31f1
Server
- Parse Server version:
3.0.2
- Operating system:
MacOS Sonoma 14.4.1
- Local or remote host (AWS, Azure, Google Cloud, Heroku, Digital Ocean, etc):
Local
Database
- System (MongoDB or Postgres):
MongoDB
- Database version:
n/a
- Local or remote host (MongoDB Atlas, mLab, AWS, Azure, Google Cloud, etc):
Local
Client
- Parse .NET SDK version:
3.0.2