Firebase:将数据传递给云函数会导致:对象无法以JSON编码

时间:2018-05-02 15:19:31

标签: android firebase google-cloud-functions

我尝试调用云函数并传递一些数据。我的数据类型为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}

我尝试了以下内容: 我尝试在数据对象中打包数组而不是Map。 =&GT;没用。

我试图将自己的数据转换为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来调用我的函数,这个JSON也不起作用。

我无法弄清楚我做错了什么。有谁知道吗?

2 个答案:

答案 0 :(得分:0)

我认为您应该从数据对象中创建并传递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;
                    }
                }
            }

答案 1 :(得分:0)

通过org.json.JSONObject而不是com.google.gson.JsonObject很好。

您不需要在firebase函数上使用地图。