-1

When my Home fragment uses regular buttons through intent to go to a new class. On the new class when I try to use RecylerVie and Firebase to show data, the data does not appear and the app crashes.

On my Firebase the nodes go from project --> to DataHome --> Home1. Home 1 has the attributes description,directions, ingredients, image, title

DataHome also has other nodes named Home2, etc. But in this case I'm only trying to show data from Home1 on this class.

database image

The logcat says Fatal Exception Main: Process: com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.tmrecipes.Model.DataHome

This is the class:

public class BeefSamosa extends AppCompatActivity {


    FirebaseDatabase mHomeFireBaseDatabase;
    RecyclerView myhomeview;
    private DatabaseReference DataHomeRef;
    private LinearLayoutManager mLinearLayoutManager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_beef_samosa);
        //Back Button
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setTitle("Beef Samosa");


        //Recycler View
        myhomeview = findViewById(R.id.beefview);
        myhomeview.setHasFixedSize(true);

        //set layout as LinearLayout
        myhomeview.setLayoutManager(new LinearLayoutManager(this));


        //send query to firebase database
        mHomeFireBaseDatabase = FirebaseDatabase.getInstance();
        DataHomeRef = mHomeFireBaseDatabase.getInstance().getReference("DataHome").child("Home1");


    }

    @Override
    public boolean onOptionsItemSelected (MenuItem item){
        int id = item.getItemId();

        if(id == android.R.id.home){
            //ends the activity
            this.finish();
        }
        return super.onOptionsItemSelected(item);
    }



    @Override
    protected void onStart() {
        super.onStart();


        Query query = FirebaseDatabase.getInstance()
                .getReference("DataHome")
                .child("Home1");

        FirebaseRecyclerOptions<DataHome> options =
                new FirebaseRecyclerOptions.Builder<DataHome>()
                        .setQuery(DataHomeRef, DataHome.class)
                        .build();

        FirebaseRecyclerAdapter<DataHome,DataHomeViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<DataHome, DataHomeViewHolder>(options) {
            @NonNull
            @Override
            public DataHomeViewHolder onCreateViewHolder(ViewGroup parent, int viewtype) {
                final View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_home_deatil, parent, false);

                return new DataHomeViewHolder(view);

            }

            @Override
            protected void onBindViewHolder(@NonNull DataHomeViewHolder holder, int position, @NonNull DataHome model) {
                    holder.setDetails(getApplicationContext(), model.getTitle(), model.getImage(), model.getDescription() , model.getIngredients(), model.getDirections());
            }
        };

        firebaseRecyclerAdapter.startListening();
        myhomeview.setAdapter(firebaseRecyclerAdapter);
    }


    //DataHomeViewHolder class

    public static class DataHomeViewHolder extends RecyclerView.ViewHolder {


        View mview;


        public DataHomeViewHolder(@NonNull View itemView) {
            super(itemView);
            mview = itemView;



        }

        public void setDetails(Context ctx, String title, String image, String description, String ingredients , String directions) {

            //Views
            TextView mHomeTitle = mview.findViewById(R.id.titlewords);
            ImageView mHomeImage = mview.findViewById(R.id.loading_pic);
            TextView mDescriptionTitle = mview.findViewById(R.id.descriptionwords);
            TextView mIngredientsTitle = mview.findViewById(R.id.ingredientwords);
            TextView mDirectionsTitle = mview.findViewById(R.id.directionwords);

            //Set data to views
            mHomeTitle.setText(title);
            mDescriptionTitle.setText(description);
            mIngredientsTitle.setText(ingredients);
            mDirectionsTitle.setText(directions);
            Picasso.get().load(image).into(mHomeImage);

        }


    }
}

My model class is:

 public class DataHome {

        public String title ,image, description, ingredients, directions;

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getImage() {
            return image;
        }

        public void setImage(String image) {
            this.image = image;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        public String getIngredients() {
            return ingredients;
        }

        public void setIngredients(String ingredients) {
            this.ingredients = ingredients;
        }

        public String getDirections() {
            return directions;
        }

        public void setDirections(String directions) {
            this.directions = directions;
        }

        public DataHome(String title, String image, String description, String ingredients, String directions){
            this.title =title;
            this.image = image;
            this.description = description;
                this.ingredients = ingredients;
                this.directions=directions;
            }

    }

Edit: The changed class is:

public class BeefSamosa extends AppCompatActivity {

private FirebaseRecyclerAdapter firebaseRecyclerAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_beef_samosa);
    //Back Button
    getSupportActionBar().setDisplayShowHomeEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setTitle("Beef Samosa");


    RecyclerView recyclerView = findViewById(R.id.beef_view);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));

    DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
    Query query = rootRef.child("DataHome");

    FirebaseRecyclerOptions<DataHome> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<DataHome>()
            .setQuery(query, DataHome.class)
            .build();


    firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<DataHome, DataHomeViewHolder>(firebaseRecyclerOptions) {
        @Override
        protected void onBindViewHolder(@NonNull DataHomeViewHolder dataHomeViewHolder, int position, @NonNull DataHome dataHome) {
            dataHomeViewHolder.setDataHome(dataHome);
        }

        @Override
        public DataHomeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.homedetail, parent, false);

            return new DataHomeViewHolder(view);
        }
    };
    recyclerView.setAdapter(firebaseRecyclerAdapter);

}

@Override
protected void onStart() {
    super.onStart();
    firebaseRecyclerAdapter.startListening();
}

@Override
protected void onStop() {
    super.onStop();

    if (firebaseRecyclerAdapter!= null) {
        firebaseRecyclerAdapter.stopListening();
    }
}


@Override
public boolean onOptionsItemSelected (MenuItem item){
    int id = item.getItemId();

    if(id == android.R.id.home){
        //ends the activity
        this.finish();
    }
    return super.onOptionsItemSelected(item);
}





//DataHomeViewHolder class

private class DataHomeViewHolder extends RecyclerView.ViewHolder {

    private TextView imagetoo, titletext, description, ingredients, directions;


    DataHomeViewHolder(View itemView){
        super(itemView);
        imagetoo = itemView.findViewById(R.id.imagetoo);
        titletext = itemView.findViewById(R.id.titletext);
        description = itemView.findViewById(R.id.description);
        ingredients = itemView.findViewById(R.id.ingredients);
        directions = itemView.findViewById(R.id.directions);
    }


    void setDataHome(DataHome DataHome) {
        String imageto = DataHome.getImage();
        imagetoo.setText(imageto);
        String titleto = DataHome.getTitle();
        titletext.setText(titleto);
        String descriptionto = DataHome.getDescription();
        description.setText(descriptionto);
        String ingredientsto = DataHome.getIngredients();
        ingredients.setText(ingredientsto);
        String directionsto = DataHome.getDirections();
        directions.setText(directionsto);
    }
}

}

OmerAlaws
  • 27
  • 6
  • What is happening when you are using this code? Have you tried to call `myhomeview.setAdapter(firebaseRecyclerAdapter);` before `firebaseRecyclerAdapter.startListening();`? – Alex Mamo Apr 26 '19 at 08:35
  • When I use the code; when I click the button on my home fragment to take me to the new page (the new page is the class I put in the question ), the new page displays nothing and the app crashes. When I try to call myhomeview.setAdapter(firebaseRecyclerAdapter); before it still doesn't display anything and crashes. – OmerAlaws Apr 26 '19 at 15:02
  • The logcat says Fatal Exception Main: Process: com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.tmrecipes.Model.DataHome at com.google.firebase.database.core.utilitiescoding.ToCustomClass(com.google.firebase:firebase-database@@16.1.0:79) ... etc. – OmerAlaws Apr 26 '19 at 20:42
  • Please also add your database structure. – Alex Mamo Apr 27 '19 at 07:37
  • I added the image above in the post – OmerAlaws Apr 27 '19 at 15:09

1 Answers1

0

You are getting the following error:

 Fatal Exception Main: Process: com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.tmrecipes.Model.DataHome

Because the children under Home1 node are strings and not DataHome objects. To solve this, you need to pass to your FirebaseRecyclerOptions object a query that points to a node where DataHome objects exist. So please change the following line of code:

Query query = FirebaseDatabase.getInstance()
            .getReference("DataHome")
            .child("Home1");

to

Query query = FirebaseDatabase.getInstance()
            .getReference("DataHome");

See, I have removed the call to .child("Home1") because this is producing the error. This change will help you display all DataHome objects that exist within the all DataHome node.

If you want to display only the details of Home1 for example, there is no need to use the Firebase-UI library, you can simply get the value of all properties and display them in a list as explained in my answer from this post:

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Alright changing the query didn't fix it right way, but I'll try doing what you explained in the other post now. – OmerAlaws Apr 27 '19 at 17:28
  • The first solution is to display `DataHome` objects and the other can help you display properties of single object. Ok, keep me posted. – Alex Mamo Apr 27 '19 at 17:32
  • I changed the class but I'm still getting an error message. I updated the question at the bottom, with the changed class shown. – OmerAlaws Apr 27 '19 at 19:24
  • com.google.firebase.database.DatabaseException: Class com.example.tmrecipes.DataHome does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped. – OmerAlaws Apr 27 '19 at 22:51
  • I was just missing the empty constructor in the DataHome class. I got it now thank you for helping me out and putting time in to help other people all the time. – OmerAlaws Apr 27 '19 at 22:59