Я пытаюсь вызвать облачную функцию и передать некоторые данные. Мои данные относятся к типу Map<String, Object>
, и внутри них снова есть вложенный Map<String, Object>
. При попытке вызвать мою функцию с помощью этого:
getHttpsCallable(function).call(data)...
Я получаю такую ошибку:
Cloud Function Exception:
java.lang.IllegalArgumentException: Object cannot be encoded in JSON: [Ljava.util.Map;@42896770
at com.google.firebase.functions.Serializer.encode(Serializer.java:136)
at com.google.firebase.functions.Serializer.encode(Serializer.java:77)
at com.google.firebase.functions.FirebaseFunctions.call(FirebaseFunctions.java:255)
at com.google.firebase.functions.FirebaseFunctions.access$100(FirebaseFunctions.java:34)
at com.google.firebase.functions.FirebaseFunctions$2.then(FirebaseFunctions.java:233)
at com.google.firebase.functions.FirebaseFunctions$2.then(FirebaseFunctions.java:225)
at com.google.android.gms.tasks.zzd.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:146)
at android.app.ActivityThread.main(ActivityThread.java:5653)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1291)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1107)
at dalvik.system.NativeStart.main(Native Method)
При печати моего объекта данных он выглядит так:
{items=[Ljava.util.Map;@42896770, element1=OzNGHzHeq6av03hRmMJ6, time=Sun May 05 04:40:00 MEZ 3918}
Я пробовал следующее: Я попытался упаковать массив вместо карты внутри моего объекта данных. => Не сработало.
Я сам пытался преобразовать свои данные в json и отправить их, это тоже не сработало.
Я сделал следующее:
Gson gson = new Gson();
String dataJSON = gson.toJson(data);
который был восстановлен в хорошо отформатированном JSON:
{"items":[{"count":1,"itemId":"94To3bKnxoWzayLdy55I"},{"count":3,"itemId":"fkNtIUxbfg5GhLJy2Dma"},{"count":1,"itemId":"sDYTp7cpQTRfWuI6CSaK"},{"count":1,"itemId":"qGGl5U0qihHnMzhBMjyb","options":["2.0","1.0","1.1","0.0"]},{"count":1,"itemId":"qGGl5U0qihHnMzhBMjyb","options":["2.0","1.0","1.1","0.1"]},{"count":1,"itemId":"qGGl5U0qihHnMzhBMjyb","options":["2.0","1.0","1.1","0.2"]},{"count":1,"itemId":"qGGl5U0qihHnMzhBMjyb","options":["2.3","1.0","1.1","0.1"]}],"storeId":"OzNGHzHeq6av03hRmMJ6","pickupTime":"May 5, 3918 4:40:00 AM"}
Но я также попытался вызвать свою функцию с жестко запрограммированным JSON, который тоже не работал.
Я не могу понять, что делаю не так. Кто-нибудь знает?
@RenaudTarnec Я сделал. Я использовал его в своем подходе для отправки prebuild json.
{items=[Ljava.util.Map;@42896770,...
не смотрит JSON ...
да. Это выглядит так, если просто попробовать то, о чем я говорю в своем первоначальном тексте вопроса. Я только что сказал в своем вопросе, что пробовал и другие вещи, в том числе создание json с помощью gson.
Можете ли вы поделиться кодом, который вы написали, с Gson для преобразования вашего java-объекта в JSON?
@RenaudTarnec: Пожалуйста, посмотрите мою правку
Позвольте нам продолжить обсуждение в чате.
Я думаю, вам следует создать и передать JSONObject из своего объекта данных. Не строка или объект данных: как это:
Gson gson = new Gson();
String jsonString = gson.toJson(data);
JSONObject jsonObj = null;
try {
jsonObj = new JSONObject(jsonString);
} catch (JSONException e) {
e.printStackTrace();
}
так как:
public Object encode(Object obj) {
if (obj != null && obj != JSONObject.NULL) {
JSONObject result;
if (obj instanceof Long) {
result = new JSONObject();
try {
result.put("@type", "type.googleapis.com/google.protobuf.Int64Value");
result.put("value", obj.toString());
return result;
} catch (JSONException var9) {
throw new RuntimeException("Error encoding Long.", var9);
}
} else if (obj instanceof Number) {
return obj;
} else if (obj instanceof String) {
return obj;
} else if (obj instanceof Boolean) {
return obj;
} else if (obj instanceof JSONObject) {
return obj;
} else if (obj instanceof JSONArray) {
return obj;
} else {
Object o;
String key;
Object value;
Iterator keys;
if (obj instanceof Map) {
result = new JSONObject();
Map<?, ?> m = (Map)obj;
keys = m.keySet().iterator();
while(keys.hasNext()) {
o = keys.next();
if (!(o instanceof String)) {
throw new IllegalArgumentException("Object keys must be strings.");
}
key = (String)o;
value = this.encode(m.get(o));
try {
result.put(key, value);
} catch (JSONException var10) {
throw new RuntimeException(var10);
}
}
return result;
} else {
JSONArray result;
if (obj instanceof List) {
result = new JSONArray();
List<?> l = (List)obj;
keys = l.iterator();
while(keys.hasNext()) {
o = keys.next();
result.put(this.encode(o));
}
return result;
} else {
JSONObject wrapped;
if (obj instanceof JSONObject) {
result = new JSONObject();
wrapped = (JSONObject)obj;
keys = wrapped.keys();
while(keys.hasNext()) {
String k = (String)keys.next();
if (!(k instanceof String)) {
throw new IllegalArgumentException("Object keys must be strings.");
}
key = k;
value = this.encode(wrapped.opt(k));
try {
result.put(key, value);
} catch (JSONException var11) {
throw new RuntimeException(var11);
}
}
return result;
} else if (!(obj instanceof JSONArray)) {
if (obj instanceof Date) {
String utc = this.dateFormat.format((Date)obj);
wrapped = new JSONObject();
try {
wrapped.put("@type", "type.googleapis.com/google.protobuf.Timestamp");
wrapped.put("value", utc);
return wrapped;
} catch (JSONException var12) {
throw new RuntimeException("Error encoding Date.", var12);
}
} else {
throw new IllegalArgumentException("Object cannot be encoded in JSON: " + obj);
}
} else {
result = new JSONArray();
JSONArray l = (JSONArray)obj;
for(int i = 0; i < l.length(); ++i) {
o = l.opt(i);
result.put(this.encode(o));
}
return result;
}
}
}
Проблема в том, что вы фактически передаете array
объектов Map
.
Поскольку Фредерик Бил показывает исходный код Functions SDK для Android, он не принимает тип массива. Он принимает объект Java Collection Map
или List
.
Поэтому вы должны изменить свой [Ljava.util.Map;
на тип List<Map>
.
Кроме того, на самом деле Firestore использует Протобуф для основного набора данных. Вы можете найти дополнительную информацию о том, как они кодируют или декодируют json с данными Protobuf, на здесь.
Передача org.json.JSONObject
вместо com.google.gson.JsonObject
работает нормально.
Вам не нужно использовать Карты для функций firebase.
Может быть, использовать библиотеку Gson mkyong.com/java/… или github.com/google/gson