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
: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
: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
放入相应的变量中。堆栈跟踪:
最佳答案
您收到以下错误:
因为您正在尝试将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
类型的,因此这将无法以您的方式进行。看到,
himno
属性有一个引用。如果要获取该文档引用,只需使用:DocumentReference documentReference = documentSnapshot.getDocumentReference("himno");
如果要使用:
Himno himno=oficio.getHimno();
然后将
himno
属性更改为Himno
类型,而不是DocumentReference
类型。您的代码中的另一个问题(正如@Anees在他的问题中所指出的那样)是
getTexto()
方法应该返回String
而不是Spanned
对象,因为这是存储在数据库中的方式。参见,
texto
属性包含一个String而不是Spanned
。但这是而不是发生错误的原因。还请注意,以下句子:
是不正确的!公共(public)无参数构造函数和公共(public)获取者都没有必要。
因此,您的类(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 。
编辑:
根据您的评论:
仅将
getTexto()
方法的返回类型从Spanned
更改为String
不会帮助您解决主要错误。您尚未共享将数据添加到数据库的方式,但实际上非常简单。首先,从那些文档中删除该
himno
属性。然后,当您添加一个新文档时,而不是添加一个DocumentReference
,而是添加一个Himno
类型的对象,正如我还看到的那样,您已经在Oficio
类中进行了声明。这也意味着,当您使用以下代码行时:Himno himno=oficio.getHimno();
将返回
Himno
类型的对象,而不是DocumentReference
。这是因为它根据其数据类型进行存储。这也可以在Cloud Firestore中完成,但是您需要根据数据库中存在的属性的数据类型来获取数据。如果您的属性类型为
DocumentReference
,则不能将其作为Himno
类型获得,除非您像这样添加它。是的,我明白了。这就是为什么我告诉您根据存储的数据类型获取数据的原因。因此,如果您将数据存储为
DocumentReference
,请根据它进行获取。如果要以Himno
的形式获取它,请首先将其以Himno
的形式存储,然后相应地获取它。编辑2:
是的,您可以做到。您是如何在数据库中添加该引用的?以与添加引用相同的方式添加
Himno
对象。通过创建类型为
Oficio
的对象向数据库添加数据时,请以正确的方式设置Himno
对象。试试这个:Oficio oficio = new Oficio();
Himno himno = new Himno();
himno.setTexto("Your Text");
oficio.setHimno(himno);
docRef.set(oficio);
是的。为了能够管理Cloud Firestore数据库,您至少应该对以下方面有基本的了解: