【问题标题】:Firestore : Get an array of object in a documentFirestore:获取文档中的对象数组
【发布时间】:2021-07-25 23:24:48
【问题描述】:

因此,在我的应用程序中,我想显示有关食谱的多个信息。在食谱中,您可以看到类别、名称……以及成分列表。我想获取此列表以显示配方的详细信息。

目前(在屏幕上)可以看到名称、类别、完成时间、难度和人数。

现在在这个屏幕上,我想要得到的结果:

我通过手动将对象添加到列表中来获得它。

ingredients.add(new Ingredient("Test", "1500"));

IngredientsAdapter adapt = new IngredientsAdapter(ViewRecette.this, R.layout.adapter_ingredients, ingredients);
listIngredients.setAdapter(adapt);

现在我正在尝试使用此代码,但我得到了这个错误。

ingredients = (ArrayList<Ingredient>) documentSnapshot.get("Ingrédients");

IngredientsAdapter adapt = new IngredientsAdapter(ViewRecette.this, R.layout.adapter_ingredients, ingredients);
listIngredients.setAdapter(adapt);

错误是:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.learncooking, PID: 21971
java.lang.ClassCastException: java.util.HashMap cannot be cast to com.example.learncooking.Ingredient
    at com.example.learncooking.IngredientsAdapter.getView(IngredientsAdapter.java:40)
    at com.example.learncooking.ViewRecette$1.onEvent(ViewRecette.java:103)
    at com.example.learncooking.ViewRecette$1.onEvent(ViewRecette.java:82)
    at com.google.firebase.firestore.DocumentReference.lambda$addSnapshotListenerInternal$2(DocumentReference.java:504)
    at com.google.firebase.firestore.DocumentReference$$Lambda$3.onEvent(Unknown Source:6)
    at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0(AsyncEventListener.java:42)
    at com.google.firebase.firestore.core.AsyncEventListener$$Lambda$1.run(Unknown Source:6)
    at android.os.Handler.handleCallback(Handler.java:900)
    at android.os.Handler.dispatchMessage(Handler.java:103)
    at android.os.Looper.loop(Looper.java:219)
    at android.app.ActivityThread.main(ActivityThread.java:8387)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)

我正在努力解决这个问题,提前感谢您的回答。

编辑 1

所以我现在正在尝试使用 POJO,但我真的不明白如何做到这一点。我正在使用以下代码(对此我不确定)但是如何使用它来显示它?

DocumentSnapshot document = (DocumentSnapshot) documentSnapshot.get("Ingrédients");;
                    if (document.exists()) {
                        IngredientPOJO notifPojo = document.toObject(IngredientPOJO.class);
                    }

还有“POJO”文件:

public class IngredientPOJO {

@SerializedName("ingredient")
@Expose
private List<Ingredient> ingredients;

public IngredientPOJO() {

}

public IngredientPOJO(List<Ingredient> ingredients) {
    this.ingredients = ingredients;
}

public List<Ingredient> getIngredients() {
    return ingredients;
}

public void setIngredients(List<Ingredient> ingredients) {
    this.ingredients = ingredients;
}

编辑 2

这里我也修改了一些小项。

private TextView nomRecette, tempsTotal, diff, nbPersonne, cat;
private ImageView receteImage;
private ListView listIngredients, listEtapes;
ArrayList<Ingredient> ingredients;
ArrayList<Etapes> etapes = new ArrayList<>();

private FirebaseFirestore firebaseFirestore;
private DocumentReference documentReference;
private FirebaseStorage firebaseStorage;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_view_recette);

    receteImage = (ImageView) findViewById(R.id.ivPhotoRecetteView);
    nomRecette = (TextView) findViewById(R.id.tvNomRecetteView);
    cat = (TextView) findViewById(R.id.tvCatégorie);
    tempsTotal = (TextView) findViewById(R.id.tvTempsTotal);
    diff = (TextView) findViewById(R.id.tvDifficulté);
    nbPersonne = (TextView) findViewById(R.id.tvNombrePersonnesView);
    listIngredients = (ListView) findViewById(R.id.lvIngredientsView);
    listEtapes = (ListView) findViewById(R.id.lvEtapesView);

    Intent intent = getIntent();
    String i = intent.getStringExtra("ID");

    firebaseFirestore = FirebaseFirestore.getInstance();
    firebaseStorage = FirebaseStorage.getInstance();

    documentReference = firebaseFirestore.collection("Recettes").document(i);
    documentReference.addSnapshotListener(ViewRecette.this, new EventListener<DocumentSnapshot>() {// Display data in TextView
        @Override
        public void onEvent(@Nullable DocumentSnapshot documentSnapshot, @Nullable FirebaseFirestoreException e) {
            if (e == null) {
                if (documentSnapshot.exists()) {

                    nomRecette.setText(documentSnapshot.getString("Nom"));
                    cat.setText(documentSnapshot.getString("Catégorie"));
                    tempsTotal.setText(documentSnapshot.getString("Temps"));
                    diff.setText(documentSnapshot.getString("Difficulté"));
                    nbPersonne.setText(documentSnapshot.getString("Nombre de personnes"));

                    if (documentSnapshot.exists()) {
                        IngredientPOJO notifPojo = documentSnapshot.toObject(IngredientPOJO.class);
                        ingredients =  new ArrayList<>();
                        ingredients.addAll(notifPojo.getIngredients());
                    }

                    IngredientsAdapter adapter = new IngredientsAdapter(ViewRecette.this, R.layout.adapter_ingredients, ingredients);
                    listIngredients.setAdapter(adapter);

最后是新的错误:

2021-05-03 21:25:28.367 5485-5485/com.example.learncooking E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.learncooking, PID: 5485
java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.Object[] java.util.Collection.toArray()' on a null object reference
    at java.util.ArrayList.addAll(ArrayList.java:588)
    at com.example.learncooking.ViewRecette$1.onEvent(ViewRecette.java:98)
    at com.example.learncooking.ViewRecette$1.onEvent(ViewRecette.java:83)
    at com.google.firebase.firestore.DocumentReference.lambda$addSnapshotListenerInternal$2(DocumentReference.java:504)
    at com.google.firebase.firestore.DocumentReference$$Lambda$3.onEvent(Unknown Source:6)
    at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0(AsyncEventListener.java:42)
    at com.google.firebase.firestore.core.AsyncEventListener$$Lambda$1.run(Unknown Source:6)
    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)

【问题讨论】:

  • 您可能需要将每个对象转换为您的 pojo。您不能直接将其转换为数组列表。看到这个线程:stackoverflow.com/questions/46639393/…
  • @MayurGajra 我已经用我现在使用的东西编辑了我的问题,我真的不知道如何继续......
  • 现在将其添加到ingredients 列表中。只需确保 ingredients 不为空即可。
  • 如果我尝试使用“ingredients.add(notifPojo)”,这是不被接受的,因为列表需要成分而不是成分POJO。抱歉,我可能很愚蠢,但我做错了什么:-/
  • 我已经发布了答案。因为,它不适合评论。所以试试看,让我们在那里继续讨论。

标签: java android firebase


【解决方案1】:

你需要改变一些东西。

IngredientPOJO 类中将 Object ingredient; 更改为 List&lt;Ingredient&gt; ingredients; 以及相应的 getter、setter 方法。

然后在这条线以下。

IngredientPOJO notifPojo = document.toObject(IngredientPOJO.class);

从该对象中获取列表并添加所有。

如下例:

IngredientPOJO notifPojo = document.toObject(IngredientPOJO.class);
ingrediants.addAll(notifPojo.getIngredient())

【讨论】:

  • 我按照您的建议进行了修改,但出现了新错误,因此我修改了问题中的 POJO 文件,然后添加了 EDIT 2。
  • @JorisRicard 确保两件事。 1) ingredientsnotifPojo 不为空。 2)您在IngredientPOJO类的SerializedName中使用了正确的键Ingrédients
  • 我修改了 IngredientPOJO 文件,尝试了所有可能的 SerializedName。我还测试了成分或 notifPojo 是否为空,但不是它们都输出变量并且错误仍然存​​在。
  • @JorisRicard 据我所知,它必须是 ingredients = (ArrayList&lt;Ingredient&gt;) documentSnapshot.get("Ingrédients"); 您需要从该行中删除 (ArrayList&lt;Ingredient&gt;) 部分。如果错误仍然存​​在。那么您能否在您的edit2中出现此错误的行旁边写一条评论?
  • 如果我删除 (ArrayList) 它不接受该行,因为“必需类型:ArrayList 并提供:对象”
猜你喜欢
  • 2018-12-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-03
  • 2023-04-02
  • 1970-01-01
  • 2021-05-14
相关资源
最近更新 更多