I am using Unity with Parse Server and now wants to be able to link a user with OAuth.
This is what I am trying so far, but with no luck.
[System.Serializable]
public class DGUOAuth
{
public string dguId = "";
public string access_token = "";
}
DGUOAuth auth = new DGUOAuth()
{
access_token = "F12w06Ddqx1k5qj75JQWRZmzh16Zgf05wHExNnHAnh8",
dguId = "25-1999"
};
System.Threading.CancellationToken canceltoken;
Dictionary<string, object> data = new Dictionary<string, object>();
data.Add("authData", auth);
Debug.Log("Ready for linking the user!");
DataManager.user.LinkWithAsync("DGU", data, canceltoken).ContinueWith(t =>
{
if (t.IsFaulted)
{
Debug.Log("Faulted: " + t.Exception);
// Errors from Parse Cloud and network interactions
using (IEnumerator<Exception> enumerator = t.Exception.InnerExceptions.GetEnumerator())
{
if (enumerator.MoveNext())
{
ParseException error = (ParseException)enumerator.Current;
Debug.Log(error.Message);
// error.Message will contain an error message
// error.Code will return "OtherCause"
}
}
}
else
{
Debug.Log("User is linked");
}
});
Nothing happens and I only get "Ready for linking the user!" but no logs after that?! The documentation for LinkWithAsync
and Unity is almost not existing...
Really hope someone can help me on this. Any help is appreciated and thanks in advance :-)
----- EDIT -----
Now, added a Debug.Log
just after t.isFaulted
and get this log:
System.AggregateException: One or more errors occurred. ---> System.ArgumentException: Unable to encode objects of type DGUOAuth
Not sure how to solve this. I do not get any error logs in the Parse server logs.
The error is basically coming from JsonUtility.Encode
public static string Encode(IDictionary<string, object> dict) { if (dict == null) throw new ArgumentNullException(); if (dict.Count == 0) return "{}"; StringBuilder builder = new StringBuilder("{"); foreach (KeyValuePair<string, object> pair in dict) { builder.Append(Encode(pair.Key)); builder.Append(":"); builder.Append(Encode(pair.Value)); builder.Append(","); } builder[builder.Length - 1] = '}'; return builder.ToString(); }
where builder.Append(Encode(pair.Value));
then tries to call Encode(object)
public static string Encode(object obj) { if (obj is IDictionary<string, object> dict) return Encode(dict); if (obj is IList<object> list) return Encode(list); if (obj is string str) { str = escapePattern.Replace(str, m => { switch (m.Value[0]) { case '\\': return "\\\\"; case '\"': return "\\\""; case '\b': return "\\b"; case '\f': return "\\f"; case '\n': return "\\n"; case '\r': return "\\r"; case '\t': return "\\t"; default: return "\\u" + ((ushort) m.Value[0]).ToString("x4"); } }); return "\"" + str + "\""; } if (obj is null) return "null"; if (obj is bool) return (bool) obj ? "true" : "false"; if (!obj.GetType().GetTypeInfo().IsPrimitive) throw new ArgumentException("Unable to encode objects of type " + obj.GetType()); return Convert.ToString(obj, CultureInfo.InvariantCulture); }
so without knowing that thing at all it looks like it simply expects an IDictionary<string, object>
where the value
can only be of the types
IDictionary<string, object>
(where the value type again underlies the same type restrictions)IList<object>
(where the element type again underlies the same restrictions)string
bool
int
, short
, ulong
, float
, etc)your given class DGUOAuth
is neither of these => ArgumentException
.
So I would simply not use your DGUOAuth
class at all but simply construct according dictionary either directly as
var data = new Dictionary<string, object>
{
{"authData" , "{\"access_token\" : \"F12w06Ddqx1k5qj75JQWRZmzh16Zgf05wHExNnHAnh8\", \"dguId\" : \"25-1999\"}"}
};
or if you want to as
var data = new Dictionary<string, object>
{
{"authData" , new Dictionary<string, object>
{
{"access_token", "F12w06Ddqx1k5qj75JQWRZmzh16Zgf05wHExNnHAnh8"},
{"dguId", "25-1999"}
}
}
};
where of course you can fill in the values also dynamically from variables if needed.
The alternative would be to make sure that your DGUOAuth
returns such a dictionary this makes it maybe easier for you if you need to pass this around a lot or configure it via the Inspector
[System.Serializable]
public class DGUOAuth
{
public string dguId = "";
public string access_token = "";
public DGUOauth(string id, string token)
{
dguId = id;
access_token = token;
}
public IDictionary<string, object> ToDictionary()
{
return new Dictionary<string, object>
{
{"access_token", access_token},
{"dguId", dguId}
};
}
}
and then use it like
var data = new Dictionary<string, object>
{
{"authData", new DGUOauth("25-1999", "F12w06Ddqx1k5qj75JQWRZmzh16Zgf05wHExNnHAnh8").ToDictionary()}
};
or actually implements according interface IDictionary<string, object>
which in my eyes is a lot of overkill for this little task.
I'm not even sure if you need that field name authData
there or if it rather simply would expect
var data = new Dictionary<string, object>
{
{"access_token", "F12w06Ddqx1k5qj75JQWRZmzh16Zgf05wHExNnHAnh8"},
{"dguId", "25-1999"}
};
but that's something you will have to try.