Search Unity

Question Error deserializing JSON credential data - Google API

Discussion in 'Scripting' started by samirgeorgy, Nov 30, 2022.

  1. samirgeorgy

    samirgeorgy

    Joined:
    Jun 3, 2018
    Posts:
    5
    Hello,

    I am facing an issue in deserializing the JSON credential data when connecting to Google API. I am building a mobile application to be built for Android. Here is the code I am using to connect to Google API:

    Code (CSharp):
    1. byte[] byteArray = Encoding.UTF8.GetBytes(jsonData);
    2. MemoryStream stream = new MemoryStream(byteArray);
    3.  
    4. ServiceAccountCredential credential = ServiceAccountCredential.FromServiceAccountData(stream);
    5.  
    6. _sheetsService = new SheetsService(new BaseClientService.Initializer()
    7. {
    8.     HttpClientInitializer = credential,
    9.     ApplicationName = _applicationName
    10. });
    I get the JSON data from a remote database via a webservice.

    The thing is this code runs perfectly when I test the program in Unity. However, when I build the APK and test it on my phone, I get the error "Error deserializing JSON credential data". I am really stuck and would appreciate any help.

    Thanks.

    PS. I am using Google API v4.
     
  2. TaleOf4Gamers

    TaleOf4Gamers

    Joined:
    Nov 15, 2013
    Posts:
    825
    Well I suppose the first step would be to attach the debugger so that you can inspect what value is actually being deserialized at that point if possible. I forget exactly what you need to enable but you will definitely be able to debug/breakpoint the code
     
  3. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,011
    Have you actually verified that the content of "jsonData" is actually valid json? Try to drop it in JsonLint or some other json verifier and see if everything is right. There's still a chance that there may be some invisible characters (a common issue is a BOM [Byte Order Mark] at the very beginning depending on where the data actually comes from on your webservice side).
     
  4. samirgeorgy

    samirgeorgy

    Joined:
    Jun 3, 2018
    Posts:
    5
    I already did that, it works perfectly when running in Unity... the problem happens when I export to APK. I tried using the logcat to check the json string and it looks fine as well!!!
     
  5. samirgeorgy

    samirgeorgy

    Joined:
    Jun 3, 2018
    Posts:
    5
    I downloaded the JSON string from Google API services... it is the credentials key that I use to connect to my google api service. but just to make sure I used the link you provided to verify the json string and it is a valid one.
     
  6. TaleOf4Gamers

    TaleOf4Gamers

    Joined:
    Nov 15, 2013
    Posts:
    825
    Which does not address my post at all. I never mentioned the difference when running in the editor, you can debug Android builds too so you can step through line-by-line looking at your data, you do not need to faf around with logging

    Out of curiosity, which part/line specifically does it error on? The exception sounds like something I would expect when turning JSON into a C# object for example however this code does not do that so I am just curious what else would throw such an error
     
  7. samirgeorgy

    samirgeorgy

    Joined:
    Jun 3, 2018
    Posts:
    5
    The error happens at line 4.

    And i would appreciate it if you can direct me to a debugger that debugs android builds.
     
  8. TaleOf4Gamers

    TaleOf4Gamers

    Joined:
    Nov 15, 2013
    Posts:
    825
    Visual Studio, just make sure the APK is a development build and script debugging is enabled in the build settings. You can also tick for the app to wait for a debugger to be attached - this means it will not run any code in your application until you tell it to continue (so that you can attach the debugger). I forget exactly what you need to do in Visual Studio but in the debug portion there is an "Attach to Process" button you may need to use once your app is started

    (This will all need to be while plugged in via USB)

    If that doesn't "just work" then try this as well (I have never needed this solution but its something I found) https://forum.unity.com/threads/cannot-debug-on-android-device-from-visual-studio.1015027/
     
    Bunny83 likes this.
  9. TaleOf4Gamers

    TaleOf4Gamers

    Joined:
    Nov 15, 2013
    Posts:
    825
    I assume by 'line 4' you mean
    Code (CSharp):
    1. ServiceAccountCredential credential = ServiceAccountCredential.FromServiceAccountData(stream);
    I imagine that ServiceAccountCredential is part of the Google library? Do you have the source for that? Can you look inside it?
     
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,011
    What do you mean by you downloaded it from the Google API? When I said you should make sure it contains valid JSON, I meant you should check it in the built game when running on the actual device. Try adding a temporary Debug.Log. Use "adb logcat" to see the log output.
     
  11. samirgeorgy

    samirgeorgy

    Joined:
    Jun 3, 2018
    Posts:
    5

    I was able to debug the APK from VS and I was able to acquire the inner exception. Here is the exception I am getting at line 4:

    Newtonsoft.Json.JsonSerializationException: Unable to find a constructor to use for type Google.Apis.Auth.OAuth2.JsonCredentialParameters. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute.

    I did some research and I read some posts about creating a link.xml file that disable bytecode stripping. here is the content of the link.xml I created:

    Code (CSharp):
    1. <linker>
    2.     <assembly fullname="AssemblyCSharp">
    3.         <type fullname="Google.Apis.Auth.OAuth2.JsonCredentialParameters">
    4.             <!-- disables stripping just for the constructor -->
    5.             <method signature="System.Void .ctor()"/>
    6.         </type>
    7.  
    8.         <!-- disables stripping for the entire type -->
    9.         <type fullname="Google.Apis.Auth.OAuth2.JsonCredentialParameters" preserve="all" />
    10.     </assembly>
    11. </linker>
    I added that file in the Assets folder and rebuilt the APK but i am still getting the same exception!
     
    Bunny83 and TaleOf4Gamers like this.
  12. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,011
    Well, now it's clear what the problem is: AOT platform and code stripping :)

    Your link.xml doesn't seem to be right unless that class is actually compiled into your AssemblyCSharp? I would bet that this is actually located in a seperate assembly, no? A quick search revealed this. So the assembly should be "Google.Apis.Auth.dll". Since the assembly name seems to be without the extension, try

    Code (CSharp):
    1.     <linker>
    2.         <assembly fullname="Google.Apis.Auth">
    3.             <type fullname="Google.Apis.Auth.OAuth2.JsonCredentialParameters" preserve="all" />
    4.         </assembly>
    5.     </linker>
    6.  
    or simply

    Code (CSharp):
    1.     <linker>
    2.         <assembly fullname="Google.Apis.Auth" preserve="all"/>
    3.     </linker>
    4.  
    This may be the better solution in case other classes are also needed from that assembly.