0

I am trying to read from relatime database the following object:

.. to a this Java Category.class:

public class Category {
    private String nombre;
    private String descripcion;
    private String estado;
    private List<String> productos;
    private List<Page> paginas;

    public Category(){}

    public Category(String name) {
        this.nombre = "";
        this.descripcion = "";
        this.estado = "";
        productos = new ArrayList<>();
        paginas = new ArrayList<>();
    }

    public String getCategoryName() {
        return nombre;
    }

    public void setCategoryName(String nombre) {
        this.nombre = nombre;
    }

    public String getCategoryDescription() {
        return descripcion;
    }

    public void setCategoryDescription(String descripcion) {
        this.descripcion = descripcion;
    }

    public String getCategoryState() {
        return estado;
    }

    public void setCategoryState(String estado) {
        this.estado = estado;
    }

    public List<String> getProducts() {
        return this.productos;
    }

    public void setProducts(List<String> productos) {
        this.productos = productos;
    }

    public List<Page> getPages() {
        return this.paginas;
    }

    public void setPages(List<Page> pages) {
        this.paginas = paginas;
    }

    @Override
    public String toString() {
        return nombre;
    }
}

I have searched and read from different sources and from what I understand I should use Maps, but the truth is, I don't know how to do it ...

This is the code of the reading, and if I debug it, I can see that the dataSnaphot has everything I need, but the Category c is null:

FirebaseDatabase.getInstance().getReference().child("categorias").addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
            Category c = snapshot.getValue(Category.class);
            list.add(c);
        }
        AdapterCategories adapter = new AdapterCategories(list);
        recycleView.setAdapter(adapter);
    }

    @Override
    public void onCancelled(DatabaseError error) {
        // Failed to read value
        Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show();
    }
});

This is the JSON exported from FIREBASE:

"categorias" : {
    "Telas de Hogar" : {
      "descripcion" : "",
      "estado" : "invisible",
      "nombre" : "Telas de Hogar",
      "paginas" : {
        "Loneta" : {
          "descripcion" : "",
          "estado" : "invisible",
          "nombre" : "Loneta"
        }
      }
    }
  }

Please could anybody help me to solve this problem.

  • You can store both a `List` and a `Map` in the database, but they result in a different JSON structure. Can you edit your question to include the JSON at `categorias` (as text, no screenshots please)? You can get this by clicking the "Export JSON" link in the overflow menu (⠇) on your [Firebase Database console](https://console.firebase.google.com/project/_/database/data). – Frank van Puffelen Feb 22 '21 at 15:22
  • At first glance the properties like `descripcion` seem to map fine. Can you `Log.d("DB", snapshot.getValue())`? And include the updated code, and its output in the question? – Frank van Puffelen Feb 22 '21 at 15:32

1 Answers1

1

You can store both a List and a Map in the database, but they result in a different JSON structure.


If you store an object with List<String> products in it, it will end up like this in the database:

"products": {
  "0": "Product one",
  "1": "Product two",
  "2": "Product three"
}

You'll notice that the keys that Firebase generates are sequential numbers, stored as string value (because all keys are stored as strings). This is how Firebase represents a List or array in the database.

So if you read a JSON like this from the database, it maps to a List<String>.


If you have a structure with keys that are no sequential numbers, for example keys that are generated by calling push(), it may look like this:

"paragraphs": {
  "-M...1": "He was an old man who fished alone in a skiff in the Gulf Stream...",
  "-M...2": "The old man was thin and gaunt with deep wrinkles in...",
  "-M...3": "Everything about him was old except his..."
}

This JSON structure maps to a Map<String, String> in Java, since the keys can not be converted to sequential numbers.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 1
    There's also a problem regarding the getters. The getter for the `nombre` property should be `getNombre()` and not `getCategoryName()`. – Alex Mamo Feb 22 '21 at 15:33
  • 1
    Good catch Alex. I had not check `category`, as there's no such property in the JSON directly under `Telas de Hogar` anyway. – Frank van Puffelen Feb 22 '21 at 15:39
  • So I have to put exactly the get/set + the attribute name in Firebase? – Emili Bellot Feb 22 '21 at 19:35
  • By default that's how Firebase knows what JSON property to map to what fields/getters/setters in your Java object. If you want control over the mapping, you can add a [`@PropertyName` annotation](https://firebase.google.com/docs/reference/android/com/google/firebase/database/PropertyName). See https://stackoverflow.com/q/38681260, https://stackoverflow.com/a/45330351 and https://stackoverflow.com/a/30943084 – Frank van Puffelen Feb 22 '21 at 19:46
  • Please don't change your question in such a way that it hides previous problems, as it outdates answers. We're trying to build a knowledge base here, so it is important that my answer still matches your original question. – Frank van Puffelen Feb 22 '21 at 20:39
  • No problem. If you go to the [revision history](https://stackoverflow.com/posts/66318371/revisions) of your question, you can roll it back (as can many other users) - and then make additions. Just keep in mind that your question was really broad, and between my answer and this comment thread we're now covering two quite different scenarios. – Frank van Puffelen Feb 22 '21 at 21:56
  • Please study [how to create a minimal, complete, verifiable example](http://stackoverflow.com/help/mcve). You had at least two separate problems: 1) the property names not matching as answered in the comment thread, 2) the `List` vs `Map` from my answer. If we have two partial solutions, the question wasn't minimal. – Frank van Puffelen Feb 22 '21 at 22:12