英文:
How do I get a DocumentReference field from Firestore?
问题
以下是翻译好的内容:
我正在尝试从 Google Firestore 检索一个对象,这是该对象:
由于我添加了属性 "soat",我在使用以下类对对象进行反序列化时遇到错误:
@Data
public class Car {
private String plate;
private String model;
private long km;
private boolean available;
private DocumentReference soat;
}
以及用于从 Firestore 检索所有 Car 对象的代码:
@Override
public List<Car> findAll() {
List<Car> empList = new ArrayList<Car>();
CollectionReference car = fb.getFirestore().collection("Cars");
ApiFuture<QuerySnapshot> querySnapshot = car.get();
try {
for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
Car emp = doc.toObject(Car.class);
empList.add(emp);
}
} catch (Exception e) {
e.printStackTrace();
}
return empList;
}
由于我添加了属性 "soat",当请求数据时我遇到了这个错误:
ERROR 7544 --- [nio-8080-exec-7] s.e.ErrorMvcAutoConfiguration$StaticView : 无法为请求 [请求路由] 和异常 [无法写入 JSON:无限递归 (StackOverflowError);嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:无限递归 (StackOverflowError) (通过引用链:com.google.cloud.firestore.FirestoreImpl["options"]->com.google.cloud.firestore.FirestoreOptions["service"]->com.google.cloud.firestore.FirestoreImpl["options"]->com.google.cloud.firestore.FirestoreOptions["service"]->com.google.cloud.firestore.FirestoreImpl["options"]->com.google.cloud.firestore.FirestoreOptions["service"]->com.google.cloud.firestore.FirestoreImpl["options"]...
->com.google.cloud.firestore.FirestoreOptions["modulus"]]) 渲染错误页面,因为响应已经被提交。因此,
以前我无法正确进行请求,因此我在我的 application.properties 中添加了以下内容:
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
编辑:刚刚尝试了这个方法,仍然遇到相同的错误
@Override
public List<Car> findAll() {
List<Car> empList = new ArrayList<Car>();
CollectionReference car = fb.getFirestore().collection("Cars");
ApiFuture<QuerySnapshot> querySnapshot = car.get();
try {
for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
String plate = doc.getData().get("plate").toString();
String model = doc.getData().get("model").toString();
long km = Long.parseLong(doc.getData().get("km").toString());
boolean available = Boolean.parseBoolean(doc.getData().get("available").toString());
DocumentReference soat = (DocumentReference) doc.getData().get("soat");
Car emp = new Car();
emp.setAvailable(available);
emp.setKm(km);
emp.setModel(model);
emp.setPlate(plate);
emp.setSoat(soat);
empList.add(emp);
}
} catch (Exception e) {
e.printStackTrace();
}
return empList;
}
-------编辑--------
我已将以下内容添加到我的 application.properties 文件中
spring.jackson.serialization.fail-on-self-references=false
现在我从 Firestore 调用中获得了以下内容:
[{"plate":"HEO628","model":"2014","km":75000,"available":true,"soat":{"path":"SOATS/HEO628","parent":{"parent":null,"id":"SOATS","path":"SOATS","firestore":{"firestore":{"firestore":{"firestore":{"firestore":{"firestore":{"firestore":{"firestore":{"firestore":...
英文:
Im trying to retrieve an object from a google Firestore, this is the object:
Since i added the atribute soat im getting erros im using this class to deserialize the object:
@Data
public class Car {
private String plate;
private String model;
private long km;
private boolean available;
private DocumentReference soat;
}
And this code to retrieve the all the Car objects from the Firestore
@Override
public List<Car> findAll() {
List<Car> empList = new ArrayList<Car>();
CollectionReference car = fb.getFirestore().collection("Cars");
ApiFuture<QuerySnapshot> querySnapshot = car.get();
try {
for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
Car emp = doc.toObject(Car.class);
empList.add(emp);
}
} catch (Exception e) {
e.printStackTrace();
}
return empList;
}
Since i added the property soat im getting this error whe requesting the data
> ERROR 7544 --- [nio-8080-exec-7] s.e.ErrorMvcAutoConfiguration$StaticView : Cannot render error page for request [request route] and exception [Could not write JSON: Infinite recursion (StackOverflowError); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (StackOverflowError) (through reference chain: com.google.cloud.firestore.FirestoreImpl["options"]->com.google.cloud.firestore.FirestoreOptions["service"]->com.google.cloud.firestore.FirestoreImpl["options"]->com.google.cloud.firestore.FirestoreOptions["service"]->com.google.cloud.firestore.FirestoreImpl["options"]->com.google.cloud.firestore.FirestoreOptions["service"]->com.google.cloud.firestore.FirestoreImpl["options"]...
> ->com.google.cloud.firestore.FirestoreOptions["credentia
["modulus"])] as the response has already been committed. As a result,
Previously i couldnt make the request properly so i added this to my application.properties
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false
Edit: just tried this aproach and still getting same error
@Override
public List<Car> findAll() {
List<Car> empList = new ArrayList<Car>();
CollectionReference car = fb.getFirestore().collection("Cars");
ApiFuture<QuerySnapshot> querySnapshot = car.get();
try {
for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
String plate=doc.getData().get("plate").toString();
String model=doc.getData().get("model").toString();
long km=Long.parseLong(doc.getData().get("km").toString());
boolean available=Boolean.parseBoolean(doc.getData().get("available").toString());
DocumentReference soat=(DocumentReference)doc.getData().get("soat");
Car emp = new Car();
emp.setAvailable(available);
emp.setKm(km);
emp.setModel(model);
emp.setPlate(plate);
emp.setSoat(soat);
empList.add(emp);
}
} catch (Exception e) {
e.printStackTrace();
}
return empList;
}
-------EDIT--------<br>
I have aded this to my application.properties
spring.jackson.serialization.fail-on-self-references=false
And now i get this from the Firestore call
[{"plate":"HEO628","model":"2014","km":75000,"available":true,"soat":{"path":"SOATS/HEO628","parent":{"parent":null,"id":"SOATS","path":"SOATS","firestore":{"firestore":{"firestore":{"firestore":{"firestore":{"firestore":{"firestore":{"firestore":{"firestore":
答案1
得分: 1
基本上,您需要创建一个类来反序列化您的 DatabaseReference,在这种情况下,类名将为SOAT
,并使用它来存储对数据库的引用。
@Data
public class Car {
private String plate;
private String model;
private long km;
private boolean available;
private SOAT soat;
private Insurance insurance;
private Techno techno;
}
然后在从 FireBase 检索信息时,您需要进行以下请求,以便指定要映射的对象类型。
public List<Car> findAll() {
List<Car> empList = new ArrayList<Car>();
CollectionReference car = fb.getFirestore().collection("Cars");
ApiFuture<QuerySnapshot> querySnapshot = car.get();
try {
for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
String plate = doc.getData().get("plate").toString();
String model = doc.getData().get("model").toString();
long km = Long.parseLong(doc.getData().get("km").toString());
boolean available = Boolean.parseBoolean(doc.getData().get("available").toString());
DocumentSnapshot soatref = fb.getFirestore().collection("SOATS").document(plate).get().get();
DocumentSnapshot technoref = fb.getFirestore().collection("Technos").document(plate).get().get();
DocumentSnapshot insuranceref = fb.getFirestore().collection("Insurances").document(plate).get().get();
SOAT soat = soatref.toObject(SOAT.class);
Techno techno = technoref.toObject(Techno.class);
Insurance insurance = insuranceref.toObject(Insurance.class);
Car emp = new Car();
emp.setAvailable(available);
emp.setKm(km);
emp.setModel(model);
emp.setPlate(plate);
emp.setSoat(soat);
emp.setInsurance(insurance);
emp.setTechno(techno);
empList.add(emp);
}
} catch (Exception e) {
}
return empList;
}
然后在调用您的 API 时,您应该获得一个正确的对象引用,如下所示。
{
"plate": "HEO628",
"model": "2014",
"km": 75000,
"available": true,
"soat": {
"expeditionDate": "2020-09-29T06:12:12.000+00:00",
"carPlate": "HEO628"
},
"insurance": {
"expeditionDate": "2020-10-01T11:12:12.000+00:00",
"carPlate": "HEO628"
},
"techno": {
"expeditionDate": "2020-09-08T17:00:00.000+00:00",
"carPlate": "HEO628"
}
}
英文:
Basically you have to create a class to deserialice your DatabaseReference, in this case the class name would be SOAT
and use it to sotre your reference to the database.
@Data
public class Car {
private String plate;
private String model;
private long km;
private boolean available;
private SOAT soat;
private Insurance insurance;
private Techno techno;
}
Then when retrieving the information from FireBase you have to make the following requests in order to specify the kind of object your are going to map.
public List<Car> findAll() {
List<Car> empList = new ArrayList<Car>();
CollectionReference car = fb.getFirestore().collection("Cars");
ApiFuture<QuerySnapshot> querySnapshot = car.get();
try {
for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
String plate = doc.getData().get("plate").toString();
String model = doc.getData().get("model").toString();
long km = Long.parseLong(doc.getData().get("km").toString());
boolean available = Boolean.parseBoolean(doc.getData().get("available").toString());
DocumentSnapshot soatref = fb.getFirestore().collection("SOATS").document(plate).get().get();
DocumentSnapshot technoref = fb.getFirestore().collection("Technos").document(plate).get().get();
DocumentSnapshot insuranceref = fb.getFirestore().collection("Insurances").document(plate).get().get();
SOAT soat = soatref.toObject(SOAT.class);
Techno techno = technoref.toObject(Techno.class);
Insurance insurance = insuranceref.toObject(Insurance.class);
Car emp = new Car();
emp.setAvailable(available);
emp.setKm(km);
emp.setModel(model);
emp.setPlate(plate);
emp.setSoat(soat);
emp.setInsurance(insurance);
emp.setTechno(techno);
empList.add(emp);
}
} catch (Exception e) {
}
return empList;
}
An then whe calling your API you shold get a proper reference to the Object like this.
{
"plate": "HEO628",
"model": "2014",
"km": 75000,
"available": true,
"soat": {
"expeditionDate": "2020-09-29T06:12:12.000+00:00",
"carPlate": "HEO628"
},
"insurance": {
"expeditionDate": "2020-10-01T11:12:12.000+00:00",
"carPlate": "HEO628"
},
"techno": {
"expeditionDate": "2020-09-08T17:00:00.000+00:00",
"carPlate": "HEO628"
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论