Reputation: 3968
This was the closest question that I found but still not what I'm looking for.
I'm using google Firestore to save user information (number, sex, etc). I use a JSON custom object to save, but when I'm trying to get the information I'm not able to transform in JSON object again.
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());
}
}
});
}
I tried to get from Task(result) the JSON object, but it won't work:
task.getResult().toObjects(JSONObject.class).get(0)
I know that I can change QuerySnapshot to DocumentSnapshot, but I still no able to get the JSON Object from.
Upvotes: 2
Views: 10083
Reputation: 123
I took @atmandhol's solution as a starting point but used the JsonObjectBuilder. I also converted the chars-string-valueType structure of Firestore back to a single JsonStructure.
Use it as inspiration (not a full-proof solution). E.g. more valueTypes than "STRING" need to be added.
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();
}
Upvotes: 1
Reputation: 11
ApiFuture<QuerySnapshot> future = db.collection(collection).get();
List<QueryDocumentSnapshot> documents = future.get().getDocuments();
Iterate through the DocumentSnapshots and use recursion to create a JSONObject.
You can use getData()
on DocumentSnapshot
object to get a Map of your Firestore Document and then you can parse the object and create your own 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;
}
Upvotes: 1
Reputation: 294
You would need to create a custom User Class and then write to firestore using that POJO as @Doug Stevenson says. see the following from the docs:
"Custom objects Using Java Map objects to represent your documents is often not very convenient, so Cloud Firestore also supports writing your own Java objects with custom classes. Cloud Firestore will internally convert the objects to supported data types."
Upvotes: 2
Reputation: 317352
Firestore doesn't store JSON. It stores key/value pairs with strongly typed values. When you read a document on Android, you have two choices to get a hold of those fields:
Upvotes: 2