'Deserializing Firebase User Data response using Newtonsoft.Json library

I am using C# to deserialize a Firebase Auth REST API Get User response using Newtonsoft.Json library. Below is a sample of the JSON output:

{
  "kind": "identitytoolkit#GetAccountInfoResponse",
  "users": [
    {
      "localId": "asdfsdsfs",
      "email": "[email protected]",
      "passwordHash": "asdsdfsdfd",
      "emailVerified": false,
      "passwordUpdatedAt": 1985545511525,
      "providerUserInfo": [
        {
          "providerId": "password",
          "federatedId": "[email protected]",
          "email": "[email protected]",
          "rawId": "[email protected]"
        }
      ],
      "validSince": "16496321050",
      "lastLoginAt": "16874526844",
      "createdAt": "164123654725",
      "lastRefreshAt": "2022-03-19T16:53:56.844Z"
    }
  ]
}

I used this code to attempt to deserialize it:

Dictionary<string, List<Dictionary<string, object>>> responseText = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, List<Dictionary<string, object>>>>(request.downloadHandler.text);

However, I get this error:

ArgumentException: Could not cast or convert from System.String to System.Collections.Generic.List1[System.Collections.Generic.Dictionary2[System.String,System.Object]]. Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable (System.Object value, System.Type initialType, System.Type targetType) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast (System.Object initialValue, System.Globalization.CultureInfo culture, System.Type targetType) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType (Newtonsoft.Json.JsonReader reader, System.Object value, System.Globalization.CultureInfo culture, Newtonsoft.Json.Serialization.JsonContract contract, System.Type targetType) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Rethrow as JsonSerializationException: Error converting value "identitytoolkit#GetAccountInfoResponse" to type 'System.Collections.Generic.List1[System.Collections.Generic.Dictionary2[System.String,System.Object]]'. Path 'kind', line 2, position 50. Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType (Newtonsoft.Json.JsonReader reader, System.Object value, System.Globalization.CultureInfo culture, Newtonsoft.Json.Serialization.JsonContract contract, System.Type targetType) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary (System.Collections.IDictionary dictionary, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonDictionaryContract contract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, System.String id) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, System.Boolean checkAdditionalContent) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.JsonSerializer.DeserializeInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.JsonSerializer.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.JsonConvert.DeserializeObject (System.String value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value, Newtonsoft.Json.JsonSerializerSettings settings) (at <7ca8898b690a4181a32a9cf767cedb1e>:0) Newtonsoft.Json.JsonConvert.DeserializeObject[T] (System.String value) (at <7ca8898b690a4181a32a9cf767cedb1e>:0)



Solution 1:[1]

The error is telling you that it can't convert a string into a List<Dictionary<string, object>> - the json values don't represent List<Dictionary<,>>.

You could deserialize the json to Dictionary<string, object> or dynamic:

Dictionary<string, object> responseText = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
// or
dynamic responseText = JsonConvert.DeserializeObject<dynamic>(json);

However, unless the json is dynamic and changing constantly, a better option is to deserialize to a concrete class or classes which model the json. There are apps online to help you convert the json to C# classes. You could use json2csharp.com, app.quicktype.io, or VisualStudio Paste JSON as Classes.

I used json2csharp, which output the following (including how to deserialize the json):

Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse);

public class ProviderUserInfo
{
    public string providerId { get; set; }
    public string federatedId { get; set; }
    public string email { get; set; }
    public string rawId { get; set; }
}

public class User
{
    public string localId { get; set; }
    public string email { get; set; }
    public string passwordHash { get; set; }
    public bool emailVerified { get; set; }
    public long passwordUpdatedAt { get; set; }
    public List<ProviderUserInfo> providerUserInfo { get; set; }
    public string validSince { get; set; }
    public string lastLoginAt { get; set; }
    public string createdAt { get; set; }
    public DateTime lastRefreshAt { get; set; }
}

public class Root
{
    public string kind { get; set; }
    public List<User> users { get; set; }
}

Online example of all 3 methods

Solution 2:[2]

use this site for convert your json to c# class

and this is your model

public class ModelDeserialize
    {
        [JsonProperty("kind")]
        public string Kind { get; set; }

        [JsonProperty("users")]
        public User[] Users { get; set; }
    }

    public class User
    {
        [JsonProperty("localId")]
        public string LocalId { get; set; }

        [JsonProperty("email")]
        public string Email { get; set; }

        [JsonProperty("passwordHash")]
        public string PasswordHash { get; set; }

        [JsonProperty("emailVerified")]
        public bool EmailVerified { get; set; }

        [JsonProperty("passwordUpdatedAt")]
        public long PasswordUpdatedAt { get; set; }

        [JsonProperty("providerUserInfo")]
        public ProviderUserInfo[] ProviderUserInfo { get; set; }

        [JsonProperty("validSince")]
        public string ValidSince { get; set; }

        [JsonProperty("lastLoginAt")]
        public string LastLoginAt { get; set; }

        [JsonProperty("createdAt")]
        public string CreatedAt { get; set; }

        [JsonProperty("lastRefreshAt")]
        public DateTimeOffset LastRefreshAt { get; set; }
    }

    public class ProviderUserInfo
    {
        [JsonProperty("providerId")]
        public string ProviderId { get; set; }

        [JsonProperty("federatedId")]
        public string FederatedId { get; set; }

        [JsonProperty("email")]
        public string Email { get; set; }

        [JsonProperty("rawId")]
        public string RawId { get; set; }
    }

finally deserialize

 var dese = JsonConvert.DeserializeObject<ModelDeserialize>(json);
 (var datas in dese.Users){
 Console.WriteLine(datas.Email);

check the example

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 haldo
Solution 2 Daniel