【问题标题】:Firebase object with sub-objects to Java classFirebase 对象与 Java 类的子对象
【发布时间】:2021-05-25 05:13:53
【问题描述】:

I am trying to read from relatime database the following object

从 Firebase 导出的 JSON 是这样的:

"categorias" : {
    "Telas de Hogar" : {
      "descripcion" : "",
      "estado" : "invisible",
      "nombre" : "Telas de Hogar",
      "paginas" : {
        "Loneta" : {
          "descripcion" : "",
          "estado" : "invisible",
          "nombre" : "Loneta"
        }
      }
    }
  }

当前班级:

package com.example.tejidospulido_app.Model.Classes;
import java.util.Map;

public class Category {
    private String nombre;
    private String descripcion;
    private String estado;
    private Map<String, String> productos;
    private Map<String, Page> paginas;

    public Category(){}

    public Category(String name) {
        this.nombre = "";
        this.descripcion = "";
        this.estado = "";
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getDescripcion() {
        return descripcion;
    }

    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    public String getEstado() {
        return estado;
    }

    public void setEstado(String estado) {
        this.estado = estado;
    }

    public Map<String, String> getProductos() {
        return this.productos;
    }

    public void setProductos(Map<String, String> productos) {
        this.productos = productos;
    }

    public Map<String, Page> getPaginas() {
        return this.paginas;
    }

    public void setPaginas(Map<String, Page> pages) {
        this.paginas = paginas;
    }

    @Override
    public String toString() {
        return nombre;
    }
}

我已经设法读取了对象及其属性,但是当我想读取 paginasproductos 时,它在 paginas 中返回 null strong> 和 productos 中的 thi 错误:

com.google.firebase.database.DatabaseException: Failed to convert value of type java.util.HashMap to String
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertString(CustomClassMapper.java:426)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:217)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(CustomClassMapper.java:179)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToParameterizedType(CustomClassMapper.java:265)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(CustomClassMapper.java:177)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.access$100(CustomClassMapper.java:48)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:593)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(CustomClassMapper.java:563)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(CustomClassMapper.java:433)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(CustomClassMapper.java:232)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(CustomClassMapper.java:80)
        at com.google.firebase.database.DataSnapshot.getValue(DataSnapshot.java:203)
        at com.example.tejidospulido_app.Vista.MenuFragment$2.onDataChange(MenuFragment.java:95)
        at com.google.firebase.database.Query$1.onDataChange(Query.java:189)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
        at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:223)
        at android.app.ActivityThread.main(ActivityThread.java:7656)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

我已经从不同的来源搜索和阅读,根据我的理解,我应该使用地图,但事实是,我不知道该怎么做......

这是读取的代码,如果我调试它,后面是调试结果的图像。

FirebaseDatabase.getInstance().getReference().child("categorias").addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
            Category c = snapshot.getValue(Category.class);
            list.add(c);
        }
        AdapterCategories adapter = new AdapterCategories(list);
        recycleView.setAdapter(adapter);
    }

    @Override
    public void onCancelled(DatabaseError error) {
        // Failed to read value
        Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show();
    }
});

【问题讨论】:

标签: java android firebase class firebase-realtime-database


【解决方案1】:

首先我要感谢Frank van PuffelenHussien Fahmy,他们在回答问题上帮助了我很多。

为了实现我的目标,我创建了两个类,Page.class 和 ProductReference.class。然后我使用 Map 在 Category.class 中引用了它们。

以下是三个类:

public class Category {
    private String nombre;
    private String descripcion;
    private String estado;
    private Map<String, ProductReference> productos;
    private Map<String, Page> paginas;

    public Category(){}

    public Category(String nombre) {
        this.nombre = nombre;
        this.descripcion = "";
        this.estado = "";
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getDescripcion() {
        return descripcion;
    }

    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    public String getEstado() {
        return estado;
    }

    public void setEstado(String estado) {
        this.estado = estado;
    }

    public Map<String, ProductReference> getProductos() {
        return this.productos;
    }

    public void setProductos(Map<String, ProductReference> productos) {
        this.productos = productos;
    }

    public Map<String, Page> getPaginas() {
        return this.paginas;
    }

    public void setPaginas(Map<String, Page> paginas) {
        this.paginas = paginas;
    }

    @Override
    public String toString() {
        return nombre;
    }
}
public class Page {
    private String nombre;
    private String descripcion;
    private String estado;
    private Map<String, ProductReference> productos;

    public Page() {
    }

    public Page(String nombre) {
        this.nombre = nombre;
        this.descripcion = "";
        this.estado = "";
    }

    public String getNombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
        this.nombre = nombre;
    }

    public String getDescripcion() {
        return descripcion;
    }

    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    public String getEstado() {
        return estado;
    }

    public void setEstado(String estado) {
        this.estado = estado;
    }

    public Map<String, ProductReference> getProductos() {
        return this.productos;
    }

    public void setProductos(Map<String, ProductReference> productos) {
        this.productos = productos;
    }

    @Override
    public String toString() {
        return nombre;
    }
}
public class ProductReference {
    private String numero;

    public ProductReference(){}

    public ProductReference(String numero) {
        this.numero = numero;
    }

    public String getNumero() {
        return numero;
    }

    public void setNumero(String numero) {
        this.numero = numero;
    }

    @Override
    public String toString() {
        return numero;
    }
}

结果如下:

【讨论】:

    【解决方案2】:

    您提到的解决方案是地图,我会帮助您想象一下 让我们从简单到复杂开始

    在您阅读本文之前请记住,地图只是一个存储键值的对象,例如 JSON 存储键值

    首先,这个 Json 中的内部 Pagena 对象看起来像

    "Loneta" : {
              "descripcion" : "",
              "estado" : "invisible",
              "nombre" : "Loneta"
            }
    

    当你想用地图来表示它时

    Map<String,String> Loneta = new HashMap();
    Loneta.put("descripcion" , "");
    Loneta.put("estado" , "invisible");
    Loneta.put("nombre" , "Loneta");
    

    所以 JSON 中的 Loneta 对象现在是一个映射 注意键“Loneta”是映射变量名称

    从中获取一些东西

    String descripcion = Loneta.get("descripcion"); 
    

    现在让我们深入了解

    "Telas de Hogar" : {
          "descripcion" : "",
          "estado" : "invisible",
          "nombre" : "Telas de Hogar",
          "paginas" : {
            "Loneta" : {
              "descripcion" : "",
              "estado" : "invisible",
              "nombre" : "Loneta"
            }
          }
        }
    

    “Telas de Hogar”可以表示为地图

    我们将使用键“Telas de Hogar”作为地图的变量名 让我们创建这个地图

    Map<String,String> Telas_de_Hogar = new HashMap();
    Telas_de_Hogar.put("descripcion" , "");
    Telas_de_Hogar.put("estado" , "invisible");
    Telas_de_Hogar.put("nombre" , "Telas de Hogar");
    

    当涉及到“paginas”键时,花点时间思考一下 “paginas”是一个键,所以它是映射变量名

    Map<String,String> paginas= new HashMap();
    

    再想想这张地图里面应该有什么

    我们有一个关键的“Loneta”和它的价值观,所以我们需要一个 Loneta 地图,还记得我们创建了它吗?

    所以把它放在“页面”中,但是这里我们需要一些改变 pagins 是字符串键和映射值的映射,包含字符串字符串的映射 所以我们需要将它的声明更改为

    Map<String, Map<String,String>> pagins = new HashMap();    
    paginas.put("Loneta", Loneta);
    

    “Loneta”是关键,Loneta 是地图对象引用

    将页面地图放入 Telas_de_Hogar 地图中

    Telas_de_Hogar.put("paginas", paginas)
    

    同样,“paginas”是关键,而 paginas 是地图对象引用

    最后是包含 Telas_de_Hogar 地图值的顶级键“类别” 让我们创建它

    Map<String,String> categorias= new HashMap();
    categorias.put("Telas de Hogar", Telas_de_Hogar);
    

    希望我的回答能帮到你

    更新:

    如果你想使用 .getValue(YourClass.class); 在您的类别类中更改它

    private Map<String, String> productos;
    

    private Map<String, Map<String, String> productos;
    

    说明: "Pagins" 是 Key String 的 Map 和 String String 的 Map Value

    请看上面我们把 Lonita 作为地图放在分页地图中

    "paginas" : {
            "Loneta" : {
              "descripcion" : "",
              "estado" : "invisible",
              "nombre" : "Loneta"
            }
    

    【讨论】:

    • 好吧,我明白你的意思,我真的很感谢你,但我正在尝试使用 getValue(Class) 选项将 JSON 对象从 firebase 转换为我的类。
    • 对于这个误会我真的很抱歉,我会更新我的答案
    猜你喜欢
    • 2021-05-24
    • 2010-10-12
    • 2019-05-31
    • 1970-01-01
    • 2014-09-08
    • 2017-11-30
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    相关资源
    最近更新 更多