S
S
SimpleName2019-01-23 21:07:47
Android
SimpleName, 2019-01-23 21:07:47

How to fix the issue when loading data from Firebase database into fragment's RecyclerView?

The fragment has a RecyclerView in which pictures should be loaded. However, during the test, the application crashes when switching to a fragment with this RecyclerView. How can this be fixed?

Here is the data structure in Firebase database
5c48ac30e8a50797216173.png
fragment code with RecyclerView
public class TestFragment extends Fragment {

    private ArrayList<GalleryGridObject> galleryList = new ArrayList<GalleryGridObject>();
    private TestAdapter mAdapter;
    private RecyclerView recyclerView;
    private DatabaseReference mDatabase;

    public TestFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.fragment_coupons, container, false);


        recyclerView = view.findViewById(R.id.my_recycler_view);

        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.hasFixedSize();
        mDatabase = FirebaseDatabase.getInstance().getReference("Data");
        mDatabase.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
                for (DataSnapshot ds : dataSnapshot.getChildren()) {
                    System.out.println(ds.getValue());
                    GalleryGridObject doc = ds.getValue(GalleryGridObject.class);

                    galleryList.add(doc);

                    mAdapter = new TestAdapter(galleryList);
                    recyclerView.setAdapter(mAdapter);
                }

                mAdapter = new TestAdapter(galleryList);
                recyclerView.setAdapter(mAdapter);
            }

            @Override
            public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) { }

            @Override
            public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) { }

            @Override
            public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) { }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                Log.w("LogFragment", "loadLog:onCancelled", databaseError.toException());
            }
        });

        return view;
    }

}

RecyclerView adapter
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder> {

    private TestFragment mContext;
    private ArrayList<GalleryGridObject> galleryArrayList;

    public TestAdapter(ArrayList<GalleryGridObject> galleryArrayList){
        //this.mContext=mContext;
        this.galleryArrayList=galleryArrayList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_coupons, parent, false);

        return new ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        GalleryGridObject gallery = galleryArrayList.get(position);
        Glide.with(mContext).load(gallery.getCompanyImage()).into(holder.imageGallery);
    }

    @Override
    public int getItemCount() {
        if(galleryArrayList==null) return 0;
        return galleryArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        public ImageView imageGallery;

        public ViewHolder(View view) {
            super(view);
            imageGallery = itemView.findViewById(R.id.coupons_picture);
        }
    }
}

model for RecyclerView
public class GalleryGridObject {

    String companyImage;

    public GalleryGridObject () {}

    public GalleryGridObject(String companyImage) {
        this.companyImage = companyImage;
    }

    public String getCompanyImage() {
        return companyImage;
    }

    public void setGalleryImage(String galleryImage) {
        this.companyImage = galleryImage;
    }
}

logcat
com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type com.example.asus.socialmap.GalleryGridObject
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertBean(com.google.firebase:[email protected]@16.0.5:423)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.deserializeToClass(com.google.firebase:[email protected]@16.0.5:214)
        at com.google.firebase.database.core.utilities.encoding.CustomClassMapper.convertToCustomClass(com.google.firebase:[email protected]@16.0.5:79)
        at com.google.firebase.database.DataSnapshot.getValue(com.google.firebase:[email protected]@16.0.5:212)
        at com.example.asus.socialmap.TestFragment$1.onChildAdded(TestFragment.java:65)
        at com.google.firebase.database.core.ChildEventRegistration.fireEvent(com.google.firebase:[email protected]@16.0.5:79)
        at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:[email protected]@16.0.5:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:[email protected]@16.0.5:55)
        at android.os.Handler.handleCallback(Handler.java:789)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6798)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
SimpleName, 2019-01-27
@SimpleName

Gotta change

private ArrayList<GalleryGridObject> galleryList = new ArrayList<>();
As a private List<GalleryGridObject> galleryList;result, the fragment (or activity) code should look like this
As a result, the fragment (or activity) code should look like this
public class TestFragment extends Fragment {

private List<GalleryGridObject> galleryList;
private TestAdapter mAdapter;
private RecyclerView recyclerView;
private DatabaseReference mRef;
private FirebaseDatabase database;

public TestFragment() {
    // Required empty public constructor
}


@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_coupons, container, false);

    recyclerView = view.findViewById(R.id.my_recycler_view);
    recyclerView.setHasFixedSize(true);
    LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    recyclerView.setLayoutManager(layoutManager);
    galleryList = new ArrayList<>();

    mAdapter = new TestAdapter(galleryList);

    database = FirebaseDatabase.getInstance();
    //mRef = database.getReference().child("Data");
    mRef = database.getReference("Data");

    mRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
            GalleryGridObject image = dataSnapshot.getValue(GalleryGridObject.class);
            galleryList.add(image);
            recyclerView.setAdapter(mAdapter);
        }

        @Override
        public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

        }

        @Override
        public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {

        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

    return view;
}

public class TestAdapter extends RecyclerView.Adapter<TestAdapter.ViewHolder>{
    private Context mContext;
    private List<GalleryGridObject> galleryArrayList;

    public TestAdapter( List<GalleryGridObject> galleryArrayList){
        //this.mContext=mContext;
        this.galleryArrayList=galleryArrayList;
    }

    @NonNull
    @Override
    public TestAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_coupons, parent, false);

        return new TestAdapter.ViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull TestAdapter.ViewHolder holder, int position) {
        //GalleryGridObject gallery = galleryArrayList.get(position);
        //Glide.with(mContext).load(galleryArrayList.get(position).getImage()).into(holder.imageGallery);
        holder.textView.setText(galleryArrayList.get(position).getTitle());
        Picasso.get().load(galleryArrayList.get(position).getImage()).into(holder.imageGallery);
    }

    @Override
    public int getItemCount() {
        if(galleryArrayList==null) return 0;
        return galleryArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        public ImageView imageGallery;
        public TextView textView;

        public ViewHolder(View view) {
            super(view);
            imageGallery = itemView.findViewById(R.id.coupons_picture);
            textView = itemView.findViewById(R.id.coupons_title);
        }
    }
}

}

Here is the model for the RecyclerView (an empty constructor is a must)
@IgnoreExtraProperties
public class GalleryGridObject {

String title, image;

public GalleryGridObject () {
    // Default constructor required for calls to DataSnapshot.getValue(User.class)
}

public GalleryGridObject(String title, String image) {
    this.title = title;
    this.image = image;
}

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

The only thing I still don’t understand is why the pictures should not immediately lie in the parent folder (in my case, Data, which we specify in mRef = database.getReference("Data");), but should have their own folders, like this (here, instead of the "Data" folder, the "KFC" folder is shown ", but the essence does not change
5c4d8fa39f25c136376594.png

D
Denis Zagaevsky, 2019-01-23
@zagayevskiy

Obviously, in firebase you have thongs, and you are trying to read your object.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question