Firestore检索嵌套对象并转换为POJO

时间:2019-02-06 00:19:34

标签: android google-cloud-firestore

我在Firestore中嵌套了对象,在该对象中,文档与登录的用户的UUID绑定在一起。

我能够通过转换为Map并在DocumentSnapshot上调用getData来获取嵌套值。然后遍历Map条目集。我通常使用Firestore的方法将结果转换回我的自定义对象(例如documentSnapshot.toObject(POJO.class)并将它们放入列表中,但是由于我将嵌套值作为Map获取,因此我需要使用像Jackson或GSON之类的东西吗?一旦完成此循环,我想转换为POJO并将每个添加到arraylist,在这种情况下为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;

}

Firestore structure

3 个答案:

答案 0 :(得分:0)

是的,您将必须找到自己的解决方案,因为Firestore SDK当前不支持将单个字段映射到Java对象。现在,它仅适用于文档的全部内容。

如果您希望SDK提供一种为您完成此映射的方法,请随时file a feature request

答案 1 :(得分:0)

对于包含包含您希望各自作为独立对象的地图的文档,GSON可以作为解决方法。因此,如果将各个字段映射到Java对象中,则以下代码是解决SDK限制的一种方法,但性能会比SDK或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;

}

答案 2 :(得分:0)

似乎this feature已添加到版本18.0.0中,该版本在询问此问题之前不久发布。 Firestore Android API支持将嵌套对象字段与它们各自的类进行相互映射。

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);