Search code examples
javaandroidfirebasefirebase-realtime-databasefirebaseui

My RecyclerView with FirebaseRecyclerAdapter does not show anything on screen


I am not sure why RecyclerView is not showing any image or data on UI.

JSON Structure of Firebase database

This is the image of structure of my Firebase database table

CategoryFragment.java

This is my fragment where I configure RecyclerView with FirebaseRecyclerAdapter. Here I think where that error is but I can't find it.

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.abdullah.livewallpapers.Interface.ItemClickListener;
import com.example.abdullah.livewallpapers.Model.CategoryItem;
import com.example.abdullah.livewallpapers.R;
import com.example.abdullah.livewallpapers.Viewholder.CategoryViewholder;
import com.firebase.ui.database.FirebaseRecyclerAdapter;
import com.firebase.ui.database.FirebaseRecyclerOptions;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.squareup.picasso.Callback;
import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;
import java.util.List;

/**
  * A simple {@link Fragment} subclass.
*/
public class CategoryFragment extends Fragment {

private static final String STR_CATEGORY_BACKGROUND = "CategoryBackground";
DatabaseReference categoryBackground;
FirebaseDatabase database;

FirebaseRecyclerOptions<CategoryItem> options;
FirebaseRecyclerAdapter<CategoryItem,CategoryViewholder> adapter;

RecyclerView recyclerView;

private static CategoryFragment INSTANCE = null;

public CategoryFragment() {

    database = FirebaseDatabase.getInstance();
    categoryBackground = database.getReference(STR_CATEGORY_BACKGROUND);

    options = new FirebaseRecyclerOptions.Builder<CategoryItem>()
            .setQuery(categoryBackground,CategoryItem.class)
            .build();

    adapter = new FirebaseRecyclerAdapter<CategoryItem, CategoryViewholder>(options) {
        @Override
        protected void onBindViewHolder(@NonNull final CategoryViewholder holder, int position, @NonNull final CategoryItem model) {


            Picasso.with(getActivity())
                    .load(model.getImageLink())
                    .networkPolicy(NetworkPolicy.OFFLINE)
                    .into(holder.backgroud_image, new Callback(){
                        @Override
                        public void onSuccess() {

                        }

                        @Override
                        public void onError() {

                            Picasso.with(getActivity())
                                    .load(model.getImageLink())
                                    .error(R.drawable.ic_terrain_black_24dp)
                                    .into(holder.backgroud_image, new Callback() {
                                        @Override
                                        public void onSuccess() {

                                        }

                                        @Override
                                        public void onError() {

                                            Log.i("category_error","error comes");
                                        }
                                    });
                        }
                    } );

            holder.category_name.setText(model.getName());

            holder.setItemClickListener(new ItemClickListener() {
                @Override
                public void onClick(View view, int postion) {

                }
            });
        }

        @NonNull
        @Override
        public CategoryViewholder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

            View itemView = LayoutInflater.from(viewGroup.getContext())
                    .inflate(R.layout.layout_category_item,viewGroup,false);

            return new CategoryViewholder(itemView);
        }
    };
}

private void setCategory() {
    adapter.startListening();
    recyclerView.setAdapter(adapter);
}

@Override
public void onStart() {
    super.onStart();
    if (adapter!=null)
    adapter.startListening();
}

@Override
public void onStop() {

    super.onStop();
    if (adapter!=null)
        adapter.stopListening();
}

@Override
public void onResume() {
    super.onResume();
    if (adapter!=null)
        adapter.startListening();
}

public static CategoryFragment getInstance() {

    if (INSTANCE == null)
        INSTANCE = new CategoryFragment();
    return INSTANCE;
}


@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_category, container, false);
    recyclerView = (RecyclerView)view.findViewById(R.id.category_recyclerview);
    recyclerView.setHasFixedSize(true);
    GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(),2);
    recyclerView.setLayoutManager(gridLayoutManager);
    setCategory();

    return view;
}

}

CategoryItem

public class CategoryItem {
    public String Name;
    public String ImageLink;
    public CategoryItem() {
    }

    public CategoryItem(String name, String imageLink) {
        Name = name;
        ImageLink = imageLink;
    }

    public String getName() {
        return Name;
    }

    public void setName(String name) {
        Name = name;
    }

    public String getImageLink() {
        return ImageLink;
    }

    public void setImageLink(String imageLink) {
        ImageLink = imageLink;
    }
}

Errors from Logcat

These are the errors that comes out in logcat.

com.google.firebase.database.DatabaseException: Found two getters or fields with conflicting case sensitivity for property: imagelink
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.addProperty(com.google.firebase:firebase-database@@16.0.6:545)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper$BeanMapper.<init>(com.google.firebase:firebase-database@@16.0.6:476)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.loadOrCreateBeanMapperForClass(com.google.firebase:firebase-database@@16.0.6:317)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(com.google.firebase:firebase-database@@16.0.6:418)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-database@@16.0.6:214)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-database@@16.0.6:79)
        at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:firebase-database@@16.0.6:212)
        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:6781)
        at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
        at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752)
        at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
        at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
        at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
        at android.support.v7.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:557)
        at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
        at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612)
        at android.support.v7.widget.GridLayoutManager.onLayoutChildren(GridLayoutManager.java:171)
        at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3924)
        at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3641)
        at android.support.v7.widget.RecyclerView.consumePendingUpdateOperations(RecyclerView.java:1888)
        at android.support.v7.widget.RecyclerView$1.run(RecyclerView.java:407)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
        at android.view.Choreographer.doCallbacks(Choreographer.java:555)
        at android.view.Choreographer.doFrame(Choreographer.java:524)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4960)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
        at dalvik.system.NativeStart.main(Native Method)
V/FA: Activity resumed, time: 5548276
I/Process: Sending signal. PID: 8700 SIG: 9
Application terminated.

Solution

  • Your POJO is confusing the Firebase SDK by publicly exposing both a property and a getter with the same name: imageLink

    public class CategoryItem {
        public String ImageLink;
    
        // ...
    
        public String getImageLink() {
            return ImageLink;
        }
    
        // ...    
    }
    

    It doesn't know which one to use, since they have the same name. What you should do instead is making the field private, and leave the accessors public, so there is not two public things with the same name:

    public class CategoryItem {
        private String Name;
        private String ImageLink;
        // ...
    }
    

    This is the standard way to create a POJO type object.