skip to Main Content

My app loads items from a list that contains categories and other items. The list is like this with the names of repeated categories.

enter image description here

What I want to do is load only the category names without repeating an existing name

Example: TV Shows, Space, Nature, Cars

My Cod:

        DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("Data");
        Query query = databaseReference.orderByChild("category");
        query.addValueEventListener(new ValueEventListener() {
            @SuppressLint("NotifyDataSetChanged")
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
               // dataList.clear();
                for (DataSnapshot dataSnapshot : snapshot.getChildren()) {
                    ModelCatMenu dataClass = dataSnapshot.getValue(ModelCatMenu.class);
                    dataList.add(dataClass);
                }

                adapter.notifyDataSetChanged();
            }

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

            }
        });

Data:

{
  "Data": {
    "-Nw1n4qAQ7FIlbDVeDCN": {
      "category": "Abstract",
      "imageLink": "https://",
      "name": "name"
    },
    "-Nw1nB5__Qwrabgu3yJe": {
      "category": "Abstract",
      "imageLink": "https://",
      "name": "name"
    },
    "-Nw1nKaT_BZUlmKXjnIy": {
      "category": "3D",
      "imageLink": "https://",
      "name": "3d"
    },
    "-Nw1nRl-PgB6DKUMSsRb": {
      "category": "Film",
      "imageLink": "https://",
      "name": "name"
    },
    "-Nw2Vfv1SkB8QVHSdPFC": {
      "category": "Film",
      "imageLink": "https://",
      "name": "name"
    },
    "-Nw2lBoNGo0z79CwXuJq": {
      "category": "Film",
      "imageLink": "https://",
      "name": "name"
    }
  }
}

I tried this but without success, something is missing

List<String> uniqueCategories = new ArrayList<>();
query.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
            Category category = snapshot.getValue(Category.class);
            String categoryName = category.getCategory();

            if (!uniqueCategories.contains(categoryName)) {
                uniqueCategories.add(categoryName);
            }

        }
     adapter.notifyDataSetChanged();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        // Trate o erro, se necessário
    }
});

2

Answers


  1. I don’t see that you are passing the updated data to the adapter, could you please a full version of your code base to be able to see what is happening?

    Login or Signup to reply.
  2. As far as I understand, you need to get unique categories from the Realtime Database from the node called Data. Unfortunately, this is not possible. There is no unique() method present inside the Query class. So when you attach a listener to the Data node, you get all data, no matter if the name property holds unique values or not.

    You can indeed get all categories from the Data node and filter them on the client but this means that you’ll always have to read the entire node. Such an operation is not only expensive but can also be considered a waste of bandwidth and resources.

    In such cases, to solve this problem, you should consider denormalizing your data by reversing your schema like this:

    db
    |
    --- categories
         |
         --- Abstract
         |    |
         |    --- imageLink: "https://"
         |    |
         |    --- name: "name"
         |
         --- 3D
         |    |
         |    --- imageLink: "https://"
         |    |
         |    --- name: "name"
         |
         --- Film
              |
              --- imageLink: "https://"
              |
              --- name: "name"
    

    Using this approach, you’ll always have unique category names, because the keys in the Realtime Database are always unique. There is no way you can have duplicate keys. To list the category names, simply use the following lines of code:

    DatabaseReference db = FirebaseDatabase.getInstance().getReference();
    DatabaseReference categoriesRef = db.child("categories");
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot ds : dataSnapshot.getChildren()) {
                String category = ds.getKey();
                Log.d("TAG", category);
            }
        }
    
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            Log.d("TAG", error.getMessage()); //Never ignore potential errors!
        }
    };
    categoriesRef.addListenerForSingleValueEvent(valueEventListener);
    

    The result in the logcat will be:

    Abstract
    3D
    Film
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search