user14999193
user14999193

Reputation:

Firestore : Get an array of object in a document

So, in my application I want to display mutiple informations about a recipe. In a recipe you can see a category, a name... And a list of ingredients. I want to get this list for display in details of recipe.

Database

For the moment (in screen) it's possible to see name, category, completion time, difficulty and number of peoples.

Base screen

Now on this screen, the result I want to get :

New result

I get it by manually adding objects to the list.

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

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

Now for this to work I am trying to use this code but I get this error.

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

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

And the error is :

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)

I am trying to solve this problem thank you in advance for your answers.

EDIT 1

So I am now trying to use POJO but I don't really understand how to do this. I am using the following code (I'm not sure about this) but how do I use it to display it ?

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

And the "POJO" file :

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;
}

EDIT 2

I also modify a few small items here.

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);

And finally here is the new error :

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)

Upvotes: 0

Views: 597

Answers (1)

Mayur Gajra
Mayur Gajra

Reputation: 9073

You need to change few things.

Inside the IngredientPOJO class change Object ingredient; to List<Ingredient> ingredients; and also the getter, setter methods accordingly.

Then below this line.

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

Get list from that object and add all.

As following example:

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

Upvotes: 0

Related Questions