2

是我发现的最接近的问题,但仍然不是我想要的。

我正在使用 google Firestore来保存用户信息(号码、性别等)。我使用 JSON 自定义对象进行保存,但是当我尝试获取信息时,我无法再次在 JSON 对象中进行转换。

private void getUserData() {
  ffDatabase.collection(Objects.requireNonNull(mAuth.getCurrentUser()).getUid()).get()
   .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
     @Override
     public void onComplete(@NonNull Task<QuerySnapshot> task) {
       if (task.isSuccessful()) {                 
         JSONObject user = new JSONObject(task.getResult()
                                         .toObjects(JSONObject.class).get(0));
         DataStorageTemporary.getInstance().setJsonUser(user);
       } else {
         Log.w("ERROR load data", "Error getting documents.", task.getException());
       }
     }
  });
}

我试图从Task(result)中获取JSON 对象,但它不起作用:

  • task.getResult().toObjects(JSONObject.class).get(0)

我知道我可以将QuerySnapshot更改为DocumentSnapshot,但我仍然无法从中获取 JSON 对象。

4

4 回答 4

2

正如@Doug Stevenson 所说,您需要创建一个自定义用户类,然后使用该 POJO 写入 firestore。从文档中查看以下内容:

“自定义对象 使用 Java Map 对象来表示您的文档通常不是很方便,因此 Cloud Firestore 还支持使用自定义类编写您自己的 Java 对象。Cloud Firestore 会在内部将对象转换为支持的数据类型。”

于 2018-06-01T09:13:58.420 回答
2

Firestore 不存储 JSON。它存储具有强类型值的键/值对。当您在 Android 上阅读文档时,您有两种选择来获取这些字段:

  1. 自动将键/值对映射到符合 JavaBeans 标准的 POJO。JSONObject 不是有效的 JavaBean 类型对象。
  2. 单独访问文档中的每个键/值对。
于 2018-05-31T23:21:02.953 回答
1
ApiFuture<QuerySnapshot> future = db.collection(collection).get();
List<QueryDocumentSnapshot> documents = future.get().getDocuments();

遍历 DocumentSnapshots 并使用递归来创建 JSONObject。您可以使用getData()on DocumentSnapshotobject 获取 Firestore 文档的 Map,然后您可以解析对象并创建自己的 JSONObject。

for (DocumentSnapshot document : documents) {

JSONObject obj = mapToJSON(document.getData());

// Other stuff here ...
}

private JSONObject mapToJSON(Map<String, Object> map) {
        JSONObject obj = new JSONObject();

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value instanceof Map) {
                Map<String, Object> subMap = (Map<String, Object>) value;
                obj.put(key, mapToJSON(subMap));
            } else if (value instanceof List) {
                obj.put(key, listToJSONArray((List) value));
            }
            else {
                obj.put(key, value);
            }
        }
        return obj;
    }

    private JSONArray listToJSONArray(List<Object> list) {
        JSONArray arr = new JSONArray();
        for(Object obj: list) {
            if (obj instanceof Map) {
                arr.add(mapToJSON((Map) obj));
            }
            else if(obj instanceof List) {
                arr.add(listToJSONArray((List) obj));
            }
            else {
                arr.add(obj);
            }
        }
        return arr;
    }
于 2019-06-19T20:34:14.287 回答
0

我以@atmandhol的解决方案为起点,但使用了 JsonObjectBuilder。我还将 Firestore 的 chars-string-valueType 结构转换回单个 JsonStructure。

用它作为灵感(不是一个完整的解决方案)。例如,需要添加比“STRING”更多的valueType 。

    private JsonObject mapToJSON(Map<String, Object> map) {

    JsonObjectBuilder builder = Json.createObjectBuilder();

    for (Map.Entry<String, Object> entry : map.entrySet()) {
        String key = entry.getKey();
        Object value = entry.getValue();
        if ( isSingleElement(value) ) {
            builder.add(key, getSingleValueAsString(((Map) value)));

        } else if (value instanceof Map) {
            Map<String, Object> subMap = (Map<String, Object>) value;
            builder.add(key, mapToJSON(subMap));
        } else if (value instanceof List) {
            builder.add(key, listToJSONArray((List<Object>) value));
        }
        else {
            builder.add(key, value.toString());
        }
    }
    return builder.build();
}

private String getSingleValueAsString(Map value) {
    if( value.get("valueType").equals("STRING") ) {
        return value.get("string").toString();
    }
    return "";
}

private boolean isSingleElement(Object value) {
    return ( value instanceof Map
            && ((Map) value).containsKey("valueType"));
}

private JsonArray listToJSONArray(List<Object> list) {
    JsonArrayBuilder builder = Json.createArrayBuilder();

    for(Object value: list) {
        if ( isSingleElement(value) ) {
            builder.add(getSingleValueAsString(((Map) value)));

        } else if (value instanceof Map) {
            builder.add(mapToJSON((Map<String, Object>) value));
        }
        else if(value instanceof List) {
            builder.add(listToJSONArray((List<Object>) value));
        }
        else {
            builder.add(value.toString());
        }
    }
    return builder.build();
}
于 2020-04-26T12:12:32.677 回答