gpt4 book ai didi

java - "RuntimeException: Could not deserialize object"从 Firestore 读取嵌套对象时

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:45:26 24 4
gpt4 key购买 nike

JSON结构:

{
"breviario": {
"metaLiturgia": {
"fecha" : "Martes 5 de febrero del 2019",
"tiempo" : "PROPIO DE LOS SANTOS",
"semana" : "",
"mensaje": "",
"salterio": "",
"color":0,
"meta": ""
},
"santo": {
"nombre": "Santa Águeda, virgen y mártir",
"vida": "Padeció el martirio en Catania (Sicilia), probablemente en la persecución de Decio. Desde la antigüedad su culto se extendió por toda la Iglesia y su nombre fue introducido en el Canon romano."
},

"oficio": {
"himno": {
"texto": "Testigos de amor~de Cristo Señor,~mártires santos.§Rosales en flor~de Cristo el olor,~mártires santos.§Palabras en luz~de Cristo Jesús,~mártires santos.§Corona inmortal~del Cristo total,~mártires santos. Amén."
},
"salmodia": {
...
Oficio :

Structure of Ofcio
public class Oficio {
private Invitatorio invitatorio;
private Himno himno;
private Salmodia salmodia;
private String oracion;
private String responsorio;
private OficioLecturas oficioLecturas;
public Oficio () {}

public Himno getHimno() {
return himno;
}

public void setHimno(Himno himno) {
this.himno = himno;
}
// ...
}
Himno :

Structure of Himno
public class Himno {
private String texto;
public Himno () {}

public Spanned getTexto() {
Spanned str = Utils.fromHtml(Utils.getFormato(texto));
return str;
}

public void setTexto(String texto) {
this.texto = texto;
}
//...
}

我试过的:
    DocumentReference docRef = db.collection("liturgia").document("breviario")
.collection("oficio").document("20190204");
docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
@Override
public void onSuccess(DocumentSnapshot documentSnapshot) {
Oficio oficio = documentSnapshot.toObject(Oficio.class);
Himno himno=oficio.getHimno();
Log.d(TAG,oficio.getOracion().toString()); //Correct
}
});

问题:

我无法读取属性 himno作为自定义类“Himno”。当我尝试时,即使我评论以下行,我也会收到“RuntimeException”: Himno himno=oficio.getHimno(); .但是我可以得到属性 oracion到对应的变量中。

堆栈跟踪:

E/AndroidRuntime: FATAL EXCEPTION: main Process: org.my.app, PID: 10532 java.lang.RuntimeException: Could not deserialize object. Can't convert object of type com.google.firebase.firestore.DocumentReference to type org.my.app.model.Himno (found in field 'himno') at com.google.firebase.firestore.util.CustomClassMapper.deserializeError(com.google.firebase:firebase-firestore@@17.1.2:524) at com.google.firebase.firestore.util.CustomClassMapper.convertBean(com.google.firebase:firebase-firestore@@17.1.2:505) at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-firestore@@17.1.2:242) at com.google.firebase.firestore.util.CustomClassMapper.deserializeToType(com.google.firebase:firebase-firestore@@17.1.2:180) at com.google.firebase.firestore.util.CustomClassMapper.access$200(com.google.firebase:firebase-firestore@@17.1.2:53) at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(com.google.firebase:firebase-firestore@@17.1.2:700) at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(com.google.firebase:firebase-firestore@@17.1.2:674) at com.google.firebase.firestore.util.CustomClassMapper.convertBean(com.google.firebase:firebase-firestore@@17.1.2:503) at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-firestore@@17.1.2:242) at com.google.firebase.firestore.util.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-firestore@@17.1.2:97) at com.google.firebase.firestore.DocumentSnapshot.toObject(com.google.firebase:firebase-firestore@@17.1.2:203) at com.google.firebase.firestore.DocumentSnapshot.toObject(com.google.firebase:firebase-firestore@@17.1.2:183)

最佳答案

您收到以下错误:

Can't convert object of type com.google.firebase.firestore.DocumentReference to type org.my.app.model.Himno (found in field 'himno')



因为您正在尝试转换 DocumentReference反对 Himno目的。 Java 中没有办法实现这一点,因为它们之间没有继承关系。

您尝试从以下位置获取的文档:
db.collection("liturgia").document("breviario").collection("oficio").document("20190204");

类型为 Oficio ,所以下面的代码行:
Oficio oficio = documentSnapshot.toObject(Oficio.class);

将工作得很好。问题是当您尝试获取 Himno嵌套在您的 Oficio 下的对象像这样的类:
Himno himno=oficio.getHimno();

这将不会以您的方式工作,因为您的 himno文档中的属性包含一个类型为 DocumentReference 的值和 不是 类型 Himno .

enter image description here

看, himno属性有引用。如果您想获得该文档引用,只需使用:
DocumentReference documentReference = documentSnapshot.getDocumentReference("himno");

如果你想使用:
Himno himno=oficio.getHimno();

然后更改 himno属性类型为 Himno而不是 DocumentReference .

正如@Anees 在他的回答中指出的那样,您的代码中的另一个问题是 getTexto()方法应返回 String而不是 Spanned对象,因为这是存储在数据库中的方式。

enter image description here

看, texto属性包含一个字符串而不是 Spanned .但这是 不是 你的错误发生的原因。

另请注意,以下句子:

Custom classes in Firestore must contain



是不正确的!公共(public)无参数构造函数和公共(public) getter 都不是必须的。

所以你的类(class)可能看起来像这样:
public class Oficio {
public Invitatorio invitatorio;
public Himno himno;
public Salmodia salmodia;
public String oracion;
public String responsorio;
public OficioLecturas oficioLecturas;
}

根本没有任何构造函数、setter 或 getter。更多信息 here .

编辑:

根据您的评论:

I changet the type of getTexto() from Spanned to String, but is not working.



仅更改 getTexto() 的返回类型来自 Spanned 的方法至 String不会帮助您解决主要错误。

I don't understand how i can change the himno property to be of type Himno and not DocumentReference.



您还没有分享将数据添加到数据库的方式,但它实际上非常简单。首先,删除 himno这些文件中的属性(property)。然后,当您添加新文档时,而不是添加 DocumentReference , 添加 Himno 类型的对象,正如我还看到您在 Oficio 中声明的那样类(class)。这也意味着,当您将使用以下代码行时:
Himno himno=oficio.getHimno();
Himno 类型的对象将被退回而不是 DocumentReference .这是因为它是根据其数据类型存储的。

In RealTimeDatabase is possible to take only one object (Oficio par example) and from this object i can get references to another nested object (Himno par example).



这也可以在 Cloud Firestore 中完成,但您需要根据它在数据库中存在的属性的数据类型来获取数据。如果您的属性(property)类型为 DocumentReference ,您无法将其作为类型 Himno ,除非你像这样添加它。

See the section named "Custom objects" in the docs



是的,我明白了。这就是为什么我告诉你根据它存储的数据类型来获取数据。因此,如果您将数据存储为 DocumentReference ,照着拿。如果你想得到它作为 Himno , 将其存储为 Himno首先,然后相应地得到它。

编辑2:

Are you telling me that in can create a field of type Himno in Firestore?



是的,你可以做到。您是如何在数据库中添加该引用的?以您添加该引用的相同方式添加 Himno目的。

I don't understand how i can achieve this.



当您通过创建 Oficio 类型的对象向数据库添加数据时,设置 Himno以正确的方式反对。尝试这个:
Oficio oficio = new Oficio();
Himno himno = new Himno();
himno.setTexto("Your Text");
oficio.setHimno(himno);
docRef.set(oficio);

I'm misunderstanding things about it?



是的。为了能够管理 Cloud Firestore 数据库,您至少应该对以下方面有基本的了解:
  • 如何在 Java 中创建对象
  • 如何设置对象属性
  • 如何将数据添加到 Cloud Firestore
  • 什么是馆藏/文件
  • Firestore 中允许的数据类型
  • 关于java - "RuntimeException: Could not deserialize object"从 Firestore 读取嵌套对象时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54534278/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com