Timon Doo
Timon Doo

Reputation: 153

Retrieve multiple data from firebase

Hey im relatively new to firebase and programming as well so im sorry if its kind of a stupid question. im struggling with retrieving a recipe

Imgur

above is the datatree from firebase and below is the code from the MainActivity

       package com.example.myapplicationdatatest;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.TextView;

import com.google.firebase.FirebaseApp;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

public class MainActivity extends AppCompatActivity {

    private TextView category;
    private TextView cookinTime;
    private TextView description;
    private TextView ingridients;
    private TextView nameOfRecipe;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_main );
        category = findViewById( R.id.category );
        cookinTime = findViewById( R.id.cookingTime );
        description = findViewById( R.id.description );
        ingridients = findViewById( R.id.ingridients );
        nameOfRecipe = findViewById( R.id.nameOfRecipe );
        FirebaseApp.initializeApp( getApplicationContext() );






        FirebaseDatabase.getInstance().getReference().child( "recipes" )
                .addListenerForSingleValueEvent( new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                            Recipe recipe = snapshot.getValue( Recipe.class );

                            category.setText( recipe.getCategory() );
                            cookinTime.setText( recipe.getCookingtime() );
                            description.setText( recipe.getDescription() );
                            ingridients.setText( recipe.getIngredients() );
                            nameOfRecipe.setText( recipe.getIngredients() );
                        }
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {
                    }
                } );
    }





}

The Layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/category"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

      />

    <TextView
        android:id="@+id/cookingTime"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <TextView
        android:id="@+id/description"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <TextView
        android:id="@+id/ingridients"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <TextView
        android:id="@+id/nameOfRecipe"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</LinearLayout>

the recipe class

    package com.example.myapplicationdatatest;

public class Recipe {

    private String category;
    private String cookingtime;
    private String description;
    private String ingredients;
    private String nameOfRecipe;

    public Recipe() {};

    public Recipe(String category, String cookingtime, String description,String ingredients, String nameOfRecipe) {
        this.category=category;
        this.cookingtime=cookingtime;
        this.description=description;
        this.ingredients=ingredients;
        this.nameOfRecipe=nameOfRecipe;
    }

    public String getCategory() {
        return category;
    }

    public String getCookingtime() {
        return cookingtime;
    }

    public String getDescription() {
        return description;
    }

    public String getIngredients() {
        return ingredients;
    }

    public String getNameOfRecipe() {
        return nameOfRecipe;
    }
}

and the Exception

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.myapplicationdatatest, PID: 6400
    com.google.firebase.database.DatabaseException: Failed to convert value of type java.util.HashMap to String
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertString(com.google.firebase:firebase-database@@19.1.0:408)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database@@19.1.0:199)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToType(com.google.firebase:firebase-database@@19.1.0:178)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.access$100(com.google.firebase:firebase-database@@19.1.0:47)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(com.google.firebase:firebase-database@@19.1.0:586)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.deserialize(com.google.firebase:firebase-database@@19.1.0:545)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(com.google.firebase:firebase-database@@19.1.0:415)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database@@19.1.0:214)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database@@19.1.0:79)
        at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database@@19.1.0:203)
        at com.example.myapplicationdatatest.MainActivity$1.onDataChange(MainActivity.java:53)
        at com.google.firebase.database.Query$1.onDataChange(com.google.firebase:firebase-database@@19.1.0:179)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database@@19.1.0:75)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database@@19.1.0:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database@@19.1.0:55)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

i really dont know how i can retrieve these multiple branches, especially since i want to add more than one recipe

thanks for your help

Upvotes: 2

Views: 732

Answers (2)

Itamar Kerbel
Itamar Kerbel

Reputation: 2568

I think what you are trying to do is get all the recipes and go over them one by one. If this is the case try this:

FirebaseDatabase.getInstance().getReference().child("recipes")
     .addListenerForSingleValueEvent(new ValueEventListener() {
     @Override
     public void onDataChange(DataSnapshot dataSnapshot) {
           for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
               Recipe recipe = snapshot.getValue(Recipe.class);//I'm assuming you have a Recipe class
               //Do something with the data
           }
     }
     @Override
     public void onCancelled(DatabaseError databaseError) {
     }
});

In your recipe class ingredients is not a String. It's a Hashmap. try:

public class Recipe {

    private String category;
    private String cookingtime;
    private String description;
    private HashMap<String, String> ingredients;
    private String nameOfRecipe;

    public Recipe() {};

    public Recipe(String category, String cookingtime, String description,HashMap<String, String>ingredients, String nameOfRecipe) {
        this.category=category;
        this.cookingtime=cookingtime;
        this.description=description;
        this.ingredients=ingredients;
        this.nameOfRecipe=nameOfRecipe;
    }

    public String getCategory() {
        return category;
    }

    public String getCookingtime() {
        return cookingtime;
    }

    public String getDescription() {
        return description;
    }

    public HashMap<String, String> getIngredients() {
        return ingredients;
    }

    public String getNameOfRecipe() {
        return nameOfRecipe;
    }
}

Upvotes: 1

Alex Mamo
Alex Mamo

Reputation: 138814

You are getting the following error:

com.google.firebase.database.DatabaseException: Failed to convert value of type java.util.HashMap to String

Because the type of the fields in your Recipe class are different than the type of the properties in your database. You have in your Recipe class a field named ingredients which is of type String while in the database I see that is a Map<String, Object> and this is not correct, hence that error. The type of the fields must match. Beside that, you have a property in your database named amountOfIngredients which is actually missing from your Recipe class. To solve this, please model your Recipe class according to the type of your properties that exist in the database and your problem will be solved.

Upvotes: 3

Related Questions