Reputation: 59
I have nested objects in Firestore where I have the document tied to the logged in user's UUID.
I am able to get the nested values out by converting to a Map and calling getData on the DocumentSnapshot. Then looping over the Map entry set. I have typically used Firestore's methods to convert the result back over to my custom object (e.g. documentSnapshot.toObject(POJO.class) and throw them in a list, but since I am getting the nested values as a Map, will I need to use something like Jackson or GSON? Once this loop is done, I want to convert to POJO and add each to the arraylist, in this case allVehices.
public ArrayList<Vehicle> getAllVehicles() {
FirebaseFirestore.getInstance().collection("vehicles")
//.whereEqualTo("vehicleUUID",FirebaseAuth.getInstance().getCurrentUser().getUid())
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot documentSnapshot : task.getResult()) {
Map<String,Object> map = (Map<String,Object>) documentSnapshot.getData();
for (Map.Entry<String,Object> entry : map.entrySet()) {
System.out.print(entry.getKey() + "/" + entry.getValue());
}
}
}
}
});
return allVehicles;
}
Upvotes: 3
Views: 1715
Reputation: 10327
It appears this feature was added in version 18.0.0 which released shortly before this question was asked. The Firestore Android API supports mapping nested object fields to and from their respective classes.
Parent.java
public class Parent {
private Child child;
public Parent() {
this(null);
}
public Parent(Child child) {
this.child = child;
}
public Child getChild() {
return child;
}
}
Child.java
public class Child {
private String value;
public Child () {
this(null);
}
public Parent(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
Repository.java
// Store Parent:
firestore.collection("collection")
.document("id1")
.set(myParent); // Add appropriate listeners
// Retrieve Parent:
client.collection("collection")
.document("id1")
.get()
// The returned Parent instance will have the child field set.
.addOnSuccessListener(snapshot -> snapshot.toObject(Parent.class);
Upvotes: 0
Reputation: 1375
GSON can work as a workaround for documents that contain maps that you would like to have each as their own individual object. So if your mapping individual fields into Java objects the below code is a workaround for SDK limitations, but will have worse performance than the SDK or Jackson.
public ArrayList<Vehicle> getAllVehicles() {
FirebaseFirestore.getInstance().collection("vehicles")
//.whereEqualTo("vehicleUUID",FirebaseAuth.getInstance().getCurrentUser().getUid())
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
@Override
public void onComplete(@NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful()) {
for (DocumentSnapshot documentSnapshot : task.getResult()) {
Map<String,Object> map = (Map<String,Object>) documentSnapshot.getData();
for (Map.Entry<String,Object> entry : map.entrySet()) {
Gson gson = new Gson();
JsonElement jsonElement = gson.toJsonTree(entry.getValue());
MyPojo pojo = gson.fromJson(jsonElement, MyPojo.class);
pojo.setKeyName(entry.getKey());
}
}
}
}
});
return allVehicles;
}
Upvotes: 1
Reputation: 317760
Yes, you will have to find your own solution to this one, as the Firestore SDK doesn't currently support mapping individual fields into Java objects. It only works with the entire contents of the document right now.
Feel free to file a feature request if you would like the SDK to provide a way to do this mapping for you.
Upvotes: 1