androidandroid-recyclerviewandroid-cardviewfirebaseuiandroid-tabbed-activity

com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.Long to type com.realty.drake.kunuk.Property


I need some help please: -What is the cause of the exceptions in my code. Is it about deserializing? -How to fix the bug? -Alternatives way to implement this?

Basically, the code is suppose to display some cardview on my fragment which content a recyclerView.

Here is the Fragment which contain most ofthe implementation

public class Tab1Buy extends Fragment {
private DatabaseReference mDatabase;
private RecyclerView mPropertyRecyclerView;
private FirebaseRecyclerAdapter<Property, Tab1Buy.PropertyViewHolder>     mPropertyAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.property_tab, container, false);
    Log.d("debbug", "onCreateView called in TAb1");
    return rootView;
}

@Override
public  void onViewCreated(View view, @Nullable Bundle savedInstanceState){
    super.onViewCreated(view, savedInstanceState);
    Log.d("debbug", "onViewCreated called in TAb");


    mDatabase =  FirebaseDatabase.getInstance().getReference().child("Property");
    mDatabase.keepSynced(true);
    //TODO might need to remove view from findBy...
    mPropertyRecyclerView = (RecyclerView) view.findViewById(R.id.property_recyclerView);
    //TODO check is this is necessary?
    DatabaseReference personRef = FirebaseDatabase.getInstance().getReference().child("Property");
    // keyQuery - the Firebase location containing the list of keys to be found in dataRef
    Query personQuery = personRef.orderByKey();
    mPropertyRecyclerView.hasFixedSize();
    mPropertyRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));



    FirebaseRecyclerOptions<Property> personsOptions =
            new FirebaseRecyclerOptions.Builder<Property>()
                    .setQuery(personQuery, Property.class)
                    .build();

    //FirebaseRecyclerOptions personsOptions = new  FirebaseRecyclerOptions.Builder<>().setQuery(personQuery, Property.class);

    mPropertyAdapter = new FirebaseRecyclerAdapter<Property, PropertyViewHolder>(personsOptions){
        @Override
        public Tab1Buy.PropertyViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
            // Create a new instance of the ViewHolder, in this case we are using a custom
            // layout called R.layout.property_card for each item
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.property_card, parent, false);
            Log.d("debbug", "onCreateViewHolder called in Adapter");
            return new Tab1Buy.PropertyViewHolder(view);

        }

        @Override
        // Bind the Chat object to the ChatHolder
        public void onBindViewHolder(Tab1Buy.PropertyViewHolder holder, final int position, final Property model){
            holder.setPrice(model.getPrice());
            Log.d("debbug", "onBindViewHolder called in TAb1");

        }


    };
    mPropertyRecyclerView.setAdapter(mPropertyAdapter);
}

@Override
public void onStart(){
    super.onStart();
    mPropertyAdapter.startListening();
}

@Override
public void onStop(){
    super.onStop();
    mPropertyAdapter.stopListening();
}




public class PropertyViewHolder extends RecyclerView.ViewHolder {

    //TODO correct itemView parm name & mView

    View mView;

    public PropertyViewHolder(View itemView) {
        super(itemView);
        mView = itemView;
        Log.d("debbug", "PropertyViewHolder RecyclerView called in TAb1");

    }

    public void setPrice(long price) {
        Log.d("debbug", "SetPrice method called PropertyViewHolder  RecyclerView called in TAb1");

        //TODO implement all the object views
        TextView post_price = (TextView) mView.findViewById(R.id.post_price);
        post_price.setText((int) price);
    }
}

}

Here is the Property class

import android.util.Log;

/**
 * Created by drake on 5/1/18.
*/

// TODO generate setters and getters
public class Property {
private int price;
private String address;
private int numberOfbed;
private int numberOfCar;
private int numberOfbath;
private String image;

public Property(){} //Needed for Firebase

public Property (int price, String address,
                 int numberOfbed, int numberOfCar,
                 int numberOfbath, String image) {
    this.address = address;
    this.price= price;
    this.numberOfbath = numberOfbath;
    this.numberOfbed = numberOfbed;
    this.numberOfCar = numberOfCar;
    this.image = image;

}



public int getPrice() {
    Log.d("debbug", "GetPrice called in Property");

    return price;
}

public void setPrice(int price) {
    this.price = price;
}

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

public int getNumberOfbed() {
    return numberOfbed;
}

public void setNumberOfbed(int numberOfbed) {
    this.numberOfbed = numberOfbed;
}

public int getNumberOfCar() {
    return numberOfCar;
}

public void setNumberOfCar(int numberOfCar) {
    this.numberOfCar = numberOfCar;
}

public int getNumberOfbath() {
    return numberOfbath;
}

public void setNumberOfbath(int numberOfbath) {
    this.numberOfbath = numberOfbath;
}

public String getImage() {
    return image;
}

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



}

This is the xml for cardview

<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dfdfdf"
android:orientation="vertical">
<!-- TODO Add white icon -->
<android.support.v7.widget.CardView  xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/tools"
    android:id="@+id/property"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:cardUseCompatPadding="true"
    card_view:cardCornerRadius="4dp"
    card_view:cardElevation="4dp">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="290dp"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/post_image"
            android:contentDescription="@string/property"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginBottom="71dp"
            android:scaleType="centerCrop"
            android:src="@drawable/house1"
            app:layout_constraintBottom_toTopOf="@+id/number_bedroom"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/post_price"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="8dp"
            android:layout_marginStart="5dp"
            android:layout_marginTop="8dp"
            android:text="55,000$"
            android:textColor="@color/colorPrimary"
            android:textSize="20sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.79" />

        <TextView
            android:id="@+id/post_address"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:layout_marginStart="5dp"
            android:layout_marginTop="1dp"
            android:text="23,Rue Duvivier-hall, Les Cayes, "
            android:textColor="#737373"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/post_price"
            app:layout_constraintVertical_bias="0.0" />

        <ImageView
            android:id="@+id/bathroom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_marginStart="100dp"
            android:layout_marginTop="2dp"
            android:background="#ff9100"
            android:src="@drawable/bathroom"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.976" />

        <ImageView
            android:id="@+id/bedroom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_marginStart="25dp"
            android:layout_marginTop="2dp"
            android:background="#ff9100"
            android:src="@drawable/bedroom"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.976" />

        <TextView
            android:id="@+id/number_bathroom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:text="2"
            android:textColor="#ff9100"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="@+id/bathroom"
            app:layout_constraintEnd_toStartOf="@+id/bathroom" />

        <TextView
            android:id="@+id/number_bedroom"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:text="3"
            android:textColor="#ff9100"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="@+id/bedroom"
            app:layout_constraintEnd_toStartOf="@+id/bedroom" />

        <TextView
            android:id="@+id/number_garage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="8dp"
            android:text="1"
            android:textColor="#ff9100"
            android:textStyle="bold"
            app:layout_constraintBottom_toBottomOf="@+id/garage"
            app:layout_constraintEnd_toStartOf="@+id/garage" />

        <ImageView
            android:id="@+id/garage"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="5dp"
            android:layout_marginStart="175dp"
            android:layout_marginTop="2dp"
            android:background="#ff9100"
            android:src="@drawable/garage"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.976" />

    </android.support.constraint.ConstraintLayout>

</android.support.v7.widget.CardView>

</LinearLayout>

Firebase node

Here's the logcat output:

05-09 21:05:00.282 8391-8391/com.realty.drake.kunuk E/RecyclerView: No adapter attached; skipping layout
05-09 21:05:00.396 8391-8420/com.realty.drake.kunuk D/FA: Connected to remote service
05-09 21:05:00.397 8391-8420/com.realty.drake.kunuk V/FA: Processing queued    up service tasks: 4
05-09 21:05:00.401 8391-8391/com.realty.drake.kunuk E/RecyclerView: No adapter attached; skipping layout
05-09 21:05:05.601 8391-8391/com.realty.drake.kunuk D/debbug: onCreateViewHolder called in Adapter
05-09 21:05:05.602 8391-8391/com.realty.drake.kunuk D/debbug: PropertyViewHolder RecyclerView called in TAb1
05-09 21:05:05.605 8391-8391/com.realty.drake.kunuk D/AndroidRuntime:  Shutting down VM
05-09 21:05:05.608 8391-8391/com.realty.drake.kunuk E/AndroidRuntime: FATAL  EXCEPTION: main
 Process: com.realty.drake.kunuk, PID: 8391
 com.google.firebase.database.DatabaseException: Can't convert object of  type java.lang.Long to type com.realty.drake.kunuk.Property
    at com.google.android.gms.internal.firebase_database.zzkt.zzb(Unknown Source)
    at com.google.android.gms.internal.firebase_database.zzkt.zza(Unknown Source)
    at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
    at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:29)
    at com.firebase.ui.database.ClassSnapshotParser.parseSnapshot(ClassSnapshotParser.java:15)
    at com.firebase.ui.common.BaseCachingSnapshotParser.parseSnapshot(BaseCachingSnapshotParser.java:35)
    at com.firebase.ui.common.BaseObservableSnapshotArray.get(BaseObservableSnapshotArray.java:52)
    at com.firebase.ui.database.FirebaseRecyclerAdapter.getItem(FirebaseRecyclerAdapter.java:106)
    at com.firebase.ui.database.FirebaseRecyclerAdapter.onBindViewHolder(FirebaseRecyclerAdapter.java:122)
    at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6482)
    at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6515)
    at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5458)
    at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5724)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5563)
    at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5559)
    at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2229)
    at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1556)
    at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1516)
    at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:608)
    at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3693)
    at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3410)
    at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3962)
    at android.view.View.layout(View.java:16647)
    at android.view.ViewGroup.layout(ViewGroup.java:5438)
    at android.support.v4.view.ViewPager.onLayout(ViewPager.java:1767)
    at android.view.View.layout(View.java:16647)
    at android.view.ViewGroup.layout(ViewGroup.java:5438)
    at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:132)
    at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
    at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1361)
    at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:869)
    at android.view.View.layout(View.java:16647)
    at android.view.ViewGroup.layout(ViewGroup.java:5438)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
    at android.view.View.layout(View.java:16647)
    at android.view.ViewGroup.layout(ViewGroup.java:5438)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
    at android.view.View.layout(View.java:16647)
    at android.view.ViewGroup.layout(ViewGroup.java:5438)
    at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
    at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
    at android.view.View.layout(View.java:16647)
    at android.view.ViewGroup.layout(ViewGroup.java:5438)
    at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
    at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
    at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
    at android.view.View.layout(View.java:16647)
    at android.view.ViewGroup.layout(ViewGroup.java`

Updated database structure

enter image description here

enter image description here

I fixed the code, Here is the full code

package com.realty.drake.kunuk;

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;


/**
 * Created by drake on 4/11/18
 */

public class Tab1Buy extends Fragment {
private DatabaseReference personRef;
private RecyclerView mPropertyRecyclerView;
FirebaseRecyclerAdapter<Property, PropertyViewHolder> mPropertyAdapter;

//*private FirebaseRecyclerAdapter<Property, PropertyViewHolder> mPropertyAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.property_tab, container, false);
    mPropertyRecyclerView = rootView.findViewById(R.id.property_recyclerView);
    return rootView;
}


@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mPropertyRecyclerView.hasFixedSize();
    mPropertyRecyclerView.setLayoutManager(new   LinearLayoutManager(getActivity()));

    personRef = FirebaseDatabase.getInstance()
            .getReference()
            .child("Property");
    personRef.keepSynced(true);
    // keyQuery - the Firebase location containing the list of keys to be found in dataRef
    //Query personQuery = personRef.orderByKey();


    FirebaseRecyclerOptions<Property> options =
            new FirebaseRecyclerOptions.Builder<Property>()
                    .setQuery(personRef, Property.class)
                    .build();

    //FirebaseRecyclerOptions personsOptions = new   FirebaseRecyclerOptions.Builder<>().setQuery(personQuery, Property.class);

    mPropertyAdapter = new FirebaseRecyclerAdapter<Property,  PropertyViewHolder>(options) {


        @Override
        // Bind the Property object to the PropertyHolder
        public void onBindViewHolder(@NonNull PropertyViewHolder holder, final int position, @NonNull final Property model) {
            holder.setPrice(model.getPrice());
            holder.setAddress(model.getAddress());
            holder.setNumberOfBed(model.getNumberOfBed());
            holder.setNumberOfBath(model.getNumberOfBath());
            holder.setNumberOfCar(model.getNumberOfCar());


        }

        @Override
        public PropertyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            // Create a new instance of the ViewHolder, in this case we are using a custom
            // layout called R.layout.property_card for each item
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.property_card, parent, false);
            return new PropertyViewHolder(view);

        }

        // @Override
        // public void onDataChanged() {
        //     // Called each time there is a new data snapshot. You may want to use this method
        //     // to hide a loading spinner or check for the "no documents" state and update your UI.
        //     // ...
        // }

        //   @Override
        //   public void onError(DatabaseError e) {
        //       // Called when there is an error getting data. You may want to update
        //       // your UI to display an error message to the user.
        //       // ...
        //   }
    };
    mPropertyRecyclerView.setAdapter(mPropertyAdapter);



}

@Override
public void onStart() {
    super.onStart();
    mPropertyAdapter.startListening();
}

@Override
public void onStop() {
    super.onStop();
    mPropertyAdapter.stopListening();
}


public class PropertyViewHolder extends RecyclerView.ViewHolder {
    View mView;

    public PropertyViewHolder(View itemView) {
        super(itemView);
        mView = itemView;
    }

    public void setPrice(int price) {
        TextView Price = (TextView) mView.findViewById(R.id.post_price);

       Price.setText(String.valueOf(price));
    }

    public void setAddress(String address){
        TextView Address = (TextView) mView.findViewById(R.id.post_address);
        Address.setText(String.valueOf(address));
    }

    public void setNumberOfBed(int numberOfBed){
        TextView NumberOfBed = (TextView) mView.findViewById(R.id.post_bedroom);
        NumberOfBed.setText(String.valueOf(numberOfBed));
    }

    public void setNumberOfBath(int numberOfBath){
        TextView NumberOfBath = (TextView) mView.findViewById(R.id.post_bathroom);
        NumberOfBath.setText(String.valueOf(numberOfBath));
    }

    public  void  setNumberOfCar(int numberOfCar) {
        TextView NumberOfCar = (TextView) mView.findViewById(R.id.post_garage);
        NumberOfCar.setText(String.valueOf(numberOfCar));
    }


}

}

Solution

  • The Problem is caused, because the structure of your database doesn't fit to your code. You need an intermediate level called Property.

    Try to change the structure of your database like this:

    enter image description here