如何从Firestore获取DocumentReference字段?

huangapple go评论101阅读模式
英文:

How do I get a DocumentReference field from Firestore?

问题

以下是翻译好的内容:

我正在尝试从 Google Firestore 检索一个对象,这是该对象:

Firestore对象

由于我添加了属性 "soat",我在使用以下类对对象进行反序列化时遇到错误:

  1. @Data
  2. public class Car {
  3. private String plate;
  4. private String model;
  5. private long km;
  6. private boolean available;
  7. private DocumentReference soat;
  8. }

以及用于从 Firestore 检索所有 Car 对象的代码:

  1. @Override
  2. public List<Car> findAll() {
  3. List<Car> empList = new ArrayList<Car>();
  4. CollectionReference car = fb.getFirestore().collection("Cars");
  5. ApiFuture<QuerySnapshot> querySnapshot = car.get();
  6. try {
  7. for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
  8. Car emp = doc.toObject(Car.class);
  9. empList.add(emp);
  10. }
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. }
  14. return empList;
  15. }

由于我添加了属性 "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 中添加了以下内容:

  1. spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false

编辑:刚刚尝试了这个方法,仍然遇到相同的错误

  1. @Override
  2. public List<Car> findAll() {
  3. List<Car> empList = new ArrayList<Car>();
  4. CollectionReference car = fb.getFirestore().collection("Cars");
  5. ApiFuture<QuerySnapshot> querySnapshot = car.get();
  6. try {
  7. for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
  8. String plate = doc.getData().get("plate").toString();
  9. String model = doc.getData().get("model").toString();
  10. long km = Long.parseLong(doc.getData().get("km").toString());
  11. boolean available = Boolean.parseBoolean(doc.getData().get("available").toString());
  12. DocumentReference soat = (DocumentReference) doc.getData().get("soat");
  13. Car emp = new Car();
  14. emp.setAvailable(available);
  15. emp.setKm(km);
  16. emp.setModel(model);
  17. emp.setPlate(plate);
  18. emp.setSoat(soat);
  19. empList.add(emp);
  20. }
  21. } catch (Exception e) {
  22. e.printStackTrace();
  23. }
  24. return empList;
  25. }

-------编辑--------

我已将以下内容添加到我的 application.properties 文件中

  1. spring.jackson.serialization.fail-on-self-references=false

现在我从 Firestore 调用中获得了以下内容:

  1. [{"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:

Firestore object

Since i added the atribute soat im getting erros im using this class to deserialize the object:

  1. @Data
  2. public class Car {
  3. private String plate;
  4. private String model;
  5. private long km;
  6. private boolean available;
  7. private DocumentReference soat;
  8. }

And this code to retrieve the all the Car objects from the Firestore

  1. @Override
  2. public List&lt;Car&gt; findAll() {
  3. List&lt;Car&gt; empList = new ArrayList&lt;Car&gt;();
  4. CollectionReference car = fb.getFirestore().collection(&quot;Cars&quot;);
  5. ApiFuture&lt;QuerySnapshot&gt; querySnapshot = car.get();
  6. try {
  7. for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
  8. Car emp = doc.toObject(Car.class);
  9. empList.add(emp);
  10. }
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. }
  14. return empList;
  15. }

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

  1. spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false

Edit: just tried this aproach and still getting same error

  1. @Override
  2. public List&lt;Car&gt; findAll() {
  3. List&lt;Car&gt; empList = new ArrayList&lt;Car&gt;();
  4. CollectionReference car = fb.getFirestore().collection(&quot;Cars&quot;);
  5. ApiFuture&lt;QuerySnapshot&gt; querySnapshot = car.get();
  6. try {
  7. for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
  8. String plate=doc.getData().get(&quot;plate&quot;).toString();
  9. String model=doc.getData().get(&quot;model&quot;).toString();
  10. long km=Long.parseLong(doc.getData().get(&quot;km&quot;).toString());
  11. boolean available=Boolean.parseBoolean(doc.getData().get(&quot;available&quot;).toString());
  12. DocumentReference soat=(DocumentReference)doc.getData().get(&quot;soat&quot;);
  13. Car emp = new Car();
  14. emp.setAvailable(available);
  15. emp.setKm(km);
  16. emp.setModel(model);
  17. emp.setPlate(plate);
  18. emp.setSoat(soat);
  19. empList.add(emp);
  20. }
  21. } catch (Exception e) {
  22. e.printStackTrace();
  23. }
  24. return empList;
  25. }

-------EDIT--------<br>
I have aded this to my application.properties

  1. spring.jackson.serialization.fail-on-self-references=false

And now i get this from the Firestore call

  1. [{&quot;plate&quot;:&quot;HEO628&quot;,&quot;model&quot;:&quot;2014&quot;,&quot;km&quot;:75000,&quot;available&quot;:true,&quot;soat&quot;:{&quot;path&quot;:&quot;SOATS/HEO628&quot;,&quot;parent&quot;:{&quot;parent&quot;:null,&quot;id&quot;:&quot;SOATS&quot;,&quot;path&quot;:&quot;SOATS&quot;,&quot;firestore&quot;:{&quot;firestore&quot;:{&quot;firestore&quot;:{&quot;firestore&quot;:{&quot;firestore&quot;:{&quot;firestore&quot;:{&quot;firestore&quot;:{&quot;firestore&quot;:{&quot;firestore&quot;:

答案1

得分: 1

基本上,您需要创建一个类来反序列化您的 DatabaseReference,在这种情况下,类名将为SOAT,并使用它来存储对数据库的引用。

  1. @Data
  2. public class Car {
  3. private String plate;
  4. private String model;
  5. private long km;
  6. private boolean available;
  7. private SOAT soat;
  8. private Insurance insurance;
  9. private Techno techno;
  10. }

然后在从 FireBase 检索信息时,您需要进行以下请求,以便指定要映射的对象类型。

  1. public List<Car> findAll() {
  2. List<Car> empList = new ArrayList<Car>();
  3. CollectionReference car = fb.getFirestore().collection("Cars");
  4. ApiFuture<QuerySnapshot> querySnapshot = car.get();
  5. try {
  6. for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
  7. String plate = doc.getData().get("plate").toString();
  8. String model = doc.getData().get("model").toString();
  9. long km = Long.parseLong(doc.getData().get("km").toString());
  10. boolean available = Boolean.parseBoolean(doc.getData().get("available").toString());
  11. DocumentSnapshot soatref = fb.getFirestore().collection("SOATS").document(plate).get().get();
  12. DocumentSnapshot technoref = fb.getFirestore().collection("Technos").document(plate).get().get();
  13. DocumentSnapshot insuranceref = fb.getFirestore().collection("Insurances").document(plate).get().get();
  14. SOAT soat = soatref.toObject(SOAT.class);
  15. Techno techno = technoref.toObject(Techno.class);
  16. Insurance insurance = insuranceref.toObject(Insurance.class);
  17. Car emp = new Car();
  18. emp.setAvailable(available);
  19. emp.setKm(km);
  20. emp.setModel(model);
  21. emp.setPlate(plate);
  22. emp.setSoat(soat);
  23. emp.setInsurance(insurance);
  24. emp.setTechno(techno);
  25. empList.add(emp);
  26. }
  27. } catch (Exception e) {
  28. }
  29. return empList;
  30. }

然后在调用您的 API 时,您应该获得一个正确的对象引用,如下所示。

  1. {
  2. "plate": "HEO628",
  3. "model": "2014",
  4. "km": 75000,
  5. "available": true,
  6. "soat": {
  7. "expeditionDate": "2020-09-29T06:12:12.000+00:00",
  8. "carPlate": "HEO628"
  9. },
  10. "insurance": {
  11. "expeditionDate": "2020-10-01T11:12:12.000+00:00",
  12. "carPlate": "HEO628"
  13. },
  14. "techno": {
  15. "expeditionDate": "2020-09-08T17:00:00.000+00:00",
  16. "carPlate": "HEO628"
  17. }
  18. }
英文:

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.

  1. @Data
  2. public class Car {
  3. private String plate;
  4. private String model;
  5. private long km;
  6. private boolean available;
  7. private SOAT soat;
  8. private Insurance insurance;
  9. private Techno techno;
  10. }

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.

  1. public List&lt;Car&gt; findAll() {
  2. List&lt;Car&gt; empList = new ArrayList&lt;Car&gt;();
  3. CollectionReference car = fb.getFirestore().collection(&quot;Cars&quot;);
  4. ApiFuture&lt;QuerySnapshot&gt; querySnapshot = car.get();
  5. try {
  6. for (DocumentSnapshot doc : querySnapshot.get().getDocuments()) {
  7. String plate = doc.getData().get(&quot;plate&quot;).toString();
  8. String model = doc.getData().get(&quot;model&quot;).toString();
  9. long km = Long.parseLong(doc.getData().get(&quot;km&quot;).toString());
  10. boolean available = Boolean.parseBoolean(doc.getData().get(&quot;available&quot;).toString());
  11. DocumentSnapshot soatref = fb.getFirestore().collection(&quot;SOATS&quot;).document(plate).get().get();
  12. DocumentSnapshot technoref = fb.getFirestore().collection(&quot;Technos&quot;).document(plate).get().get();
  13. DocumentSnapshot insuranceref = fb.getFirestore().collection(&quot;Insurances&quot;).document(plate).get().get();
  14. SOAT soat = soatref.toObject(SOAT.class);
  15. Techno techno = technoref.toObject(Techno.class);
  16. Insurance insurance = insuranceref.toObject(Insurance.class);
  17. Car emp = new Car();
  18. emp.setAvailable(available);
  19. emp.setKm(km);
  20. emp.setModel(model);
  21. emp.setPlate(plate);
  22. emp.setSoat(soat);
  23. emp.setInsurance(insurance);
  24. emp.setTechno(techno);
  25. empList.add(emp);
  26. }
  27. } catch (Exception e) {
  28. }
  29. return empList;
  30. }

An then whe calling your API you shold get a proper reference to the Object like this.

  1. {
  2. &quot;plate&quot;: &quot;HEO628&quot;,
  3. &quot;model&quot;: &quot;2014&quot;,
  4. &quot;km&quot;: 75000,
  5. &quot;available&quot;: true,
  6. &quot;soat&quot;: {
  7. &quot;expeditionDate&quot;: &quot;2020-09-29T06:12:12.000+00:00&quot;,
  8. &quot;carPlate&quot;: &quot;HEO628&quot;
  9. },
  10. &quot;insurance&quot;: {
  11. &quot;expeditionDate&quot;: &quot;2020-10-01T11:12:12.000+00:00&quot;,
  12. &quot;carPlate&quot;: &quot;HEO628&quot;
  13. },
  14. &quot;techno&quot;: {
  15. &quot;expeditionDate&quot;: &quot;2020-09-08T17:00:00.000+00:00&quot;,
  16. &quot;carPlate&quot;: &quot;HEO628&quot;
  17. }
  18. }

huangapple
  • 本文由 发表于 2020年10月5日 03:11:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/64198805.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定