How to display multiple users' image using Firebase storage on RecyclerView - android

Good day everyone, I am having a bit of a struggle trying to grasp the idea on how to retrieve data from my Firebase storage to display it to my RecyclerView. The way my application is being set up, each user is able to set their own user profile picture. So the way I store the picture to cater for every user is by naming the files according to their UID. See below:
Here is my Firestore
Now I am stumped as to how I am going to display it on my RecyclerView. Currently, my RecyclerView can display the user's FullName, Email and Score like shown below:
Here's are the code that I am currently working with right now:
UserModel
public class UserModel {
private String FullName;
private String Email;
private long Score;
public UserModel() {
}
public UserModel(String fullName, String email, long score) {
this.FullName = fullName;
this.Email = email;
this.Score = score;
}
public String getFullName() {
return FullName;
}
public void setFullName(String fullName) {
FullName = fullName;
}
public String getEmail() {
return Email;
}
public void setEmail(String email) {
Email = email;
}
public long getScore() {
return Score;
}
public void setScore(long score) {
Score = score;
}
UserAdapter
public class UserAdapter extends FirestoreRecyclerAdapter<UserModel,
UserAdapter.UserViewHolder> {
public UserAdapter(#NonNull FirestoreRecyclerOptions<UserModel> options) {
super(options);
}
#Override
protected void onBindViewHolder(#NonNull UserAdapter.UserViewHolder holder, int position, #NonNull UserModel model) {
holder.username.setText(model.getFullName());
holder.email.setText(model.getEmail());
holder.score.setText(model.getScore()+"");
}
#NonNull
#Override
public UserAdapter.UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_leaderboard_single, parent, false);
return new UserViewHolder(view);
}
public class UserViewHolder extends RecyclerView.ViewHolder {
CircleImageView userImage;
TextView username;
TextView email;
TextView score;
public UserViewHolder(#NonNull View itemView) {
super(itemView);
userImage = itemView.findViewById(R.id.list_image);
username = itemView.findViewById(R.id.list_username);
email = itemView.findViewById(R.id.list_email);
score = itemView.findViewById(R.id.list_score);
}
}
The Main Activity
public class Leaderboard extends Fragment{
private RecyclerView leaderboard_recycler;
private FirestoreRecyclerAdapter adapter;
private StorageReference storageReference;
FirebaseFirestore fStore;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_leaderboard, container, false);
leaderboard_recycler = view.findViewById(R.id.leaderboard_list);
setUpRecyclerView();
return view;
}
#Override
public void onStop() {
super.onStop();
if(adapter != null)
adapter.stopListening();
}
#Override
public void onStart() {
super.onStart();
if(adapter != null)
adapter.startListening();
}
private void setUpRecyclerView() {
fStore = FirebaseFirestore.getInstance();
//Query
Query query = fStore.collection("users")
.orderBy("Score", Query.Direction.DESCENDING);
//RecyclerOptions
FirestoreRecyclerOptions<UserModel> options = new FirestoreRecyclerOptions.Builder<UserModel>()
.setQuery(query, UserModel.class)
.build();
adapter = new UserAdapter(options);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
leaderboard_recycler.setLayoutManager(linearLayoutManager);
leaderboard_recycler.setAdapter(adapter);
leaderboard_recycler.invalidate();
}
}
I would be eternally grateful if someone can point me to the right direction on how to handle this situation. Thank you.

Your user model class should contain a property called "profilePictureUrl", which is a String type variable for storing the image url.
You should make a screen (Activity or Fragment) for user to upload their pictures to the Firebase Storage, and Firebase Storage will return that file url, just save/update it to your user object.
For displaying the images, use the modern image loading library Glide.
Firebase Storage tutorial: https://youtu.be/r4HgdJKM5ko
Glide tutorial: https://youtu.be/eiP-vnSM0OM
My Chat app demo: https://youtu.be/iTXCn3NVqDM

Related

Can't retrieve data from cloud firestore firebase

I send data from the activity to the cloud firestore and I retrieve it in the second activity in recycler view.
but the data doesn't appear in the second activity.
I used FirestoreRecyclerAdapter and FirestoreOptions.
This is the activity in which I retrieve the data.
public class MyServicesActivity extends AppCompatActivity {
private FirestoreRecyclerAdapter adapter;
private RecyclerView recyclerView;
private FirebaseFirestore db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_services);
db = FirebaseFirestore.getInstance();
Query query = db.collection("Services Requested");
recyclerView = findViewById(R.id.rv_my_services);
FirestoreRecyclerOptions<ServiceModel> response = new FirestoreRecyclerOptions
.Builder<ServiceModel>()
.setQuery(query, ServiceModel.class)
.build();
adapter = new FirestoreRecyclerAdapter<ServiceModel, ServiceHolder>(response) {
#NonNull
#Override
public ServiceHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.service_design, parent, false);
return new ServiceHolder(v);
}
#SuppressLint("SetTextI18n")
#Override
protected void onBindViewHolder(#NonNull ServiceHolder holder, int position, #NonNull ServiceModel model) {
holder.serviceImage.setImageResource(model.getServiceImage());
Log.d("DATA", "data isn't null" + position);
holder.serviceName.setText(model.getServiceName());
holder.servicePrice.setText(model.getPrice() + "" + " L.E");
}
};
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
public class ServiceHolder extends RecyclerView.ViewHolder {
private ImageView serviceImage;
private TextView serviceName, servicePrice;
public ServiceHolder(#NonNull View itemView) {
super(itemView);
serviceImage = itemView.findViewById(R.id.polish_img);
serviceName = itemView.findViewById(R.id.polish_txt);
servicePrice = itemView.findViewById(R.id.price_txt);
}
}
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
adapter.startListening();
}
}
This is the class model for retrieve data from cloud firestore
public class ServiceModel {
private String serviceName;
private int price;
private int serviceImage;
public ServiceModel(){}
public ServiceModel(String serviceName, int price, int serviceImage) {
this.serviceName = serviceName;
this.price = price;
this.serviceImage = serviceImage;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public void setPrice(int price) {
this.price = price;
}
public void setServiceImage(int serviceImage) {
this.serviceImage = serviceImage;
}
public String getServiceName() {
return serviceName;
}
public int getPrice() {
return price;
}
public int getServiceImage() {
return serviceImage;
}
}
I see in your screenshot, that the name of the properties in the database are stored using whitespace between the words, and each word is starting with a capital letter, while in your class, there is no whitespace and the first word starts with a lower-case and the second with a capital letter. When you are using a public getter called getServiceName(), Firebase is looking in the database after a property called serviceName, which actually does not exist.
To solve this, you either change the properties in your database to match the one in the class, remove the actual data, and add a fresh one, or you can use an annotation called PropertyName in front of the getter, to match the actual naming.

How to retrieve just specific data in Recycler View using Firebase Database?

I have a problem with retrieving specific data from Firebase Realtime Database. My problem is that I want to display in RecyclerView just the materials that has the Course_ID (as you can see in the image below) equals to the Course_ID (see Course -> Teacher-Courses in Firebase). How can I accomplish that thing? I will attach the code used in the RecyclerView and the class that contains the model.
As a mention: 1.I have tried to add all the course id's from Firebase and store them to a List, but the app doesn't show anything and 2. In another class I have an Intent that sends me here and also send a extra String with Course_ID that I have accesed.
I am waiting for your responses. Thank you!
FileMaterial.class
public class FileMaterial {
private String Course_ID;
private String Denumire_material;
private String Locatie_material;
private String Teacher_ID;
public FileMaterial() {
}
public FileMaterial(String course_ID, String denumire_material, String locatie_material, String teacher_ID) {
Course_ID = course_ID;
Denumire_material = denumire_material;
Locatie_material = locatie_material;
Teacher_ID = teacher_ID;
}
public String getCourse_ID() {
return Course_ID;
}
public void setCourse_ID(String course_ID) {
Course_ID = course_ID;
}
public String getDenumire_material() {
return Denumire_material;
}
public void setDenumire_material(String denumire_material) {
Denumire_material = denumire_material;
}
public String getLocatie_material() {
return Locatie_material;
}
public void setLocatie_material(String locatie_material) {
Locatie_material = locatie_material;
}
public String getTeacher_ID() {
return Teacher_ID;
}
public void setTeacher_ID(String teacher_ID) {
Teacher_ID = teacher_ID;
}
CourseMaterial.class
public class CourseMaterial extends AppCompatActivity {
private RecyclerView recyclerView;
private DatabaseReference reference, userReference;
private FirebaseAuth mAuth;
FirebaseRecyclerOptions<FileMaterial> options;
FirebaseRecyclerAdapter<FileMaterial, CourseMaterial.FileViewHolder> adapter;
ImageView btnAddMaterial;
ImageView deleteMaterial;
StorageReference storageReference;
FirebaseStorage firebaseStorage;
String urlReference;
String value;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_course_material);
value = getIntent().getStringExtra("course id").toString();
mAuth = FirebaseAuth.getInstance();
reference = FirebaseDatabase.getInstance().getReference().child("Materials").child(mAuth.getCurrentUser().getUid());
recyclerView = findViewById(R.id.recyclerView_fileMaterials);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
btnAddMaterial = findViewById(R.id.addMaterials);
btnAddMaterial.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(CourseMaterial.this, UploadFile.class));
}
});
}
#Override
public void onStart() {
super.onStart();
options = new FirebaseRecyclerOptions.Builder<FileMaterial>().setQuery(reference, FileMaterial.class).build();
adapter = new FirebaseRecyclerAdapter<FileMaterial, FileViewHolder>(options) {
#Override
protected void onBindViewHolder(#NonNull final FileViewHolder fileViewHolder, int i, #NonNull final FileMaterial fileMaterial) {
fileViewHolder.denumire_material.setText(fileMaterial.getDenumire_material());
}
#NonNull
#Override
public FileViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.youtube_view,parent, false);
FileViewHolder fileViewHolder = new FileViewHolder(v);
return fileViewHolder;
}
};
adapter.startListening();
recyclerView.setAdapter(adapter);
}
public static class FileViewHolder extends RecyclerView.ViewHolder{
TextView denumire_material, dataMaterial;
ImageView deleteMaterial;
public FileViewHolder(#NonNull View itemView) {
super(itemView);
denumire_material = itemView.findViewById(R.id.txtDenMaterial);
deleteMaterial = itemView.findViewById(R.id.imgDeleteMaterial);
}
}
Maybe make a query and pass it to the options of the adapter:
#Override
public void onStart() {
super.onStart();
Query query = reference.orderByChild("Course_ID").equalTo(value);
options = new FirebaseRecyclerOptions.Builder<FileMaterial>().setQuery(query, FileMaterial.class).build();
.......
.......
.......

Retrieve Image and name from firebase database in recycler view [duplicate]

everyone, I was trying to make a music app, and for this, I Created a Horizontal RecyclerView in my HomeFragment and my horizontal RecyclerView is getting an image with artist name.
But after clicking I load another Activity. In my other activity, I was trying to load SongsData from firebase in a listView with RecyclerView.
But the problem is I am not getting data from Firebase and it is returning null data. I provided my code below and here is the screenshot of my Firebase database:- ScreenShot
My List Class:-
public class TestUploads
{
private String songName;
private String songImageUri;
private String songUrl;
private String artistName;
public TestUploads() {
}
public String getSongName() {
return songName;
}
public void setSongName(String SongName) {
this.songName = SongName;
}
public String getSongImageUri() {
return songImageUri;
}
public void setSongImageUri(String SongImageUri) {
this.songImageUri = SongImageUri;
}
public String getSongUrl() {
return songUrl;
}
public void setSongUrl(String SongUrl) {
this.songUrl = songUrl;
}
public TestUploads(String SongImageUri, String SongName, String SongUrl ) {
this.songName = SongName;
this.artistName = SongImageUri;
this.songUrl = SongUrl;
}
}
My Adapter Class:-
public class TestAdapter extends RecyclerView.Adapter<TestAdapter.TestViewHolder>{
private Context mContext;
private List<TestUploads> mUploads;
public TestAdapter(Context context , List<TestUploads> uploads) {
mContext = context;
mUploads = uploads;
}
#NonNull
#Override
public TestViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.test_package_layout , parent ,false);
return new TestViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull TestViewHolder holder, int position) {
TestUploads uploadcurrent = mUploads.get(position);
holder.name.setText(uploadcurrent.getSongName());
Glide.with(mContext)
.load(uploadcurrent.getSongImageUri())
.into(holder.image_view);
}
#Override
public int getItemCount() {
return mUploads
.size();
}
public class TestViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView artist_name;
public CircleImageView image_view;
public TestViewHolder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.test_package_song_name);
artist_name = itemView.findViewById(R.id.test_package_artist_name);
image_view = itemView.findViewById(R.id.test_package_image_name);
}
}
}
My Activity:-
public class TestActivity extends AppCompatActivity {
private ValueEventListener listener;
private DatabaseReference reference;
private List<TestUploads> mUploads;
private RecyclerView mRecyclerView;
private TestAdapter adapter;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test_package_activity);
reference = FirebaseDatabase.getInstance().getReference("ArtistView").child(getIntent().getStringExtra("Artist"))
.child("Songs");
Toast.makeText(this, "" + getIntent().getStringExtra("Artist"), Toast.LENGTH_SHORT).show();
mUploads = new ArrayList<>();
mRecyclerView = findViewById(R.id.test_pacakge_recyclerView);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.smoothScrollToPosition(0);
adapter = new TestAdapter(this , mUploads);
mRecyclerView.setAdapter(adapter);
listener = reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
mUploads.clear();
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
TestUploads uploads =postSnapshot.getValue(TestUploads.class);
mUploads.add(uploads);
}
adapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
Sorry for so much code but this is not hard to solve. If you find the solution please reply to me. Thanks for reading this.
The problem in your code lies in the fact that the names of the fields in your TestUploads class are different than the name of the properties in your database. You have in your TestUploads class a field named songName but in your database, I see it as SongName and this is not correct. The names must match. When you are using a getter named getSongName(), Firebase is looking in the database for a field named songName and not SongName. See the lowercase s letter vs. capital letter S?
There are two ways in which you can solve this problem. The first one would be to remove the data in your database and add it again using field names that start with lowercase, as exist in your TestUploads class.
If you are not allowed to use the first solution, then the second approach will be to use annotations. So you should use the PropertyName annotation in front of the getters. So in your TestUploads class, a getter should look like this:
#PropertyName("SongName")
public String getSongName() {
return songName;
}

Android: reading a value from a child with FirebaseUI

I am using FirebaseUI to get some values from my real-time database to Firebase RecyclerView. So.. my data looks like that:
users:
userid:
info:
Name:Muhammad
I don't know how to get the value of Name which means what exactly should I do in the Users class? Here is my code (I think that the problem is in class user, I just don't know how to access child info)
public class User {
private String name;
private String email;
private String state;
private String image;
private String thumbnail;
public User(String name, String state, String image) {
this.name = name;
this.state = state;
this.image = image;
}
public User() {
}
public String getName() {
return name;
}
public String getState() {
return state;
}
public String getImage() {
return image;
}
}
my Main Activity
myDB refer to and on start method (updated after SUPERCILEX comment )
mDb = FirebaseDatabase.getInstance().getReference().child(App_Constants.USERS_COLUMN);
#Override
protected void onStart() {
super.onStart();
Query query = mDb;
FirebaseRecyclerOptions<User> options = new FirebaseRecyclerOptions.Builder<User>()
.setQuery(query, new SnapshotParser<User>() {
#NonNull
#Override
public User parseSnapshot(#NonNull DataSnapshot snapshot) {
String Name = snapshot.child(App_Constants.INFO_COLUMN).child(App_Constants.NAME_COLUMN).getValue().toString();
String State = snapshot.child(App_Constants.INFO_COLUMN).child(App_Constants.STATE_COLUMN).getValue().toString();
String Image = snapshot.child(App_Constants.INFO_COLUMN).child(App_Constants.IMAGE_COLUMN).getValue().toString();
User user = new User(Name,State,Image);
return user;
}
}).build();
FirebaseRecyclerAdapter<User,Users_ViewHolder> adapter = new FirebaseRecyclerAdapter<User, Users_ViewHolder>(options) {
#NonNull
#Override
public Users_ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_user,parent,false);
return new Users_ViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull Users_ViewHolder holder, int position, #NonNull User model) {
holder.Set_Name(model.getName());
holder.Set_Image(model.getImage());
holder.Set_State(model.getState());
}
};
mUsers.setAdapter(adapter);
}
my ViewHolder
public class Users_ViewHolder extends RecyclerView.ViewHolder{
View mView;
public Users_ViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void Set_Name(String Name)
{
TextView mName = mView.findViewById(R.id.tv_single_user_name);
mName.setText(Name);
}
public void Set_Image(String url)
{
CircleImageView mImage = mView.findViewById(R.id.iv_single_user);
Picasso.get().load(url).placeholder(R.drawable.profile).into(mImage);
}
public void Set_State(String State)
{
TextView mState = mView.findViewById(R.id.tv_single_user_state);
mState.setText(State);
}
}
thanks
I believe it'll come in as a Map<String, Object> on the field info. However, you can always use a custom SnapshotParser to build your model to your liking: https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md#using-the-firebaserecycleradapter.
Some Advices :would you mind changing the set methods names?
from Set_State to setState,I too had similar problems please respect Java naming conventions
Also add the set methods in your custom model
Second:
FirebaseRecyclerOptions<User> options =
new FirebaseRecyclerOptions.Builder<User>()
.setQuery(query, User.class)
.build();
Start Listening:
#Override
protected void onStart() {
super.onStart();
adapter.startListening();
}
stopListening() call removes the event listener and all data in the adapter
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
}
Here you have a very good explained example

How do I make the image and name of categories show on screen

For this I am using Firebase as the database and Picasso to load the images on screen. After I login I am unable to see the images and the names of each category.
I have used a model name "Category" with setters and getters but these messages keep on coming up on my logcat:
My model looks like this at the moment:
public class Category {
private String name, image;
public Category() {
}
public Category(String name, String image) {
this.name = name;
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
This is a sample of my database. it shows the category image link and the name of it.
The list of categories are supposed to show in a fragment. This is my fragment class.
public class CategoryFragment extends Fragment {
View myFragment;
RecyclerView categoryList;
RecyclerView.LayoutManager layoutManager;
FirebaseRecyclerAdapter<Category, CategoryViewHolder> adapter;
// Firebase Tings
FirebaseDatabase database;
DatabaseReference categories;
public static CategoryFragment newInstance() {
CategoryFragment categoryFragment = new CategoryFragment();
return categoryFragment;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = FirebaseDatabase.getInstance();
categories = database.getReference("Category");
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
myFragment = inflater.inflate(R.layout.fragment_category, container, false);
categoryList = (RecyclerView) myFragment.findViewById(R.id.categoryList);
categoryList.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(container.getContext());
categoryList.setLayoutManager(layoutManager);
loadCategories();
return myFragment;
}
private void loadCategories() {
adapter = new FirebaseRecyclerAdapter<Category, CategoryViewHolder>(
Category.class,
R.layout.category_item,
CategoryViewHolder.class,
categories
) {
#Override
protected void populateViewHolder(CategoryViewHolder viewHolder, final Category model, int position) {
viewHolder.tvCategoryName.setText(model.getName());
Picasso.with(getActivity())
.load(model.getImage())
.into(viewHolder.ivCategoryImage);
viewHolder.setItemClickListener(new ItemClickListener() {
#Override
public void onClick(View view, int position, boolean isLongClick) {
Toast.makeText(getActivity(), String.format("%s | %s", adapter.getRef(position).getKey(), model.getName()), Toast.LENGTH_SHORT).show();
}
});
}
};
adapter.notifyDataSetChanged();
categoryList.setAdapter(adapter);
}
}
This is my CategoryViewHolder class
public class CategoryViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView tvCategoryName;
public ImageView ivCategoryImage;
private ItemClickListener itemClickListener;
public CategoryViewHolder(View itemView) {
super(itemView);
ivCategoryImage = (ImageView) itemView.findViewById(R.id.ivCategoryImage);
tvCategoryName = (TextView) itemView.findViewById(R.id.tvCategoryName);
itemView.setOnClickListener(this);
}
public void setItemClickListener(ItemClickListener itemClickListener) {
this.itemClickListener = itemClickListener;
}
#Override
public void onClick(View view) {
itemClickListener.onClick(view, getAdapterPosition(), false);
}
}
I have looked for different solutions view the category image and names, but no luck.
UPDATE:
I have updated the database to this structure
I have tried using these 2 ways of showing the data on device
categories=FirebaseDatabase.getInstance().getReference().child("Category");
/*database = FirebaseDatabase.getInstance();
categories = database.getReference("Category");*/
But still no success.
Instead it shows the same errors. I have not changed my model in any way
Thanks for the help in advance.
P.S thanks for the solutions mentioned before, too bad it did work.
Any more help would be suffice.
The database structure from your link seems to be like this
category
|-category
|01
-------name
-------image
you should refer to the second category node to be able to reach your data
but you don't seem to do that.
So instead of using these 2 lines of code
database = FirebaseDatabase.getInstance();
categories = database.getReference("Category");
try to use this
DatabaseReference categories;
//and refer to your database like that
categories=FirebaseDatabase.getInstance().getReference().child("Category").child("Category");
according to the link you added this should be the correct way to refer to your database
Your current database structure has Category objects nested under the /Category/Category node, but the reference you are using for your FirebaseRecyclerAdapter is pointing to the parent /Category node.
This is causing the errors in your logs - the FirebaseRecyclerAdapter is trying to marshal the children of the /Category node into the Category class, but there are no matching direct children at that location.
To fix this, you can adjust the reference that the FirebaseRecyclerAdapter is using:
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = FirebaseDatabase.getInstance();
categories = database.getReference("Category").child("Category");
}
Or, change your database structure so that categories are listed as direct children of the /Category node:
{
"Category" : {
"01" : {
"Name" : "Animals",
"image" : "..."
},
"02" : {
...
}
}
}

Categories

Resources