ReDLaNN
ReDLaNN

Reputation: 524

Firebase save Object with Map property

I would like to know if it's possible to save an object containing a Map property, something like the following:

public class Item {
    public String id;
    public String name;
    public double price;
    public Map<String, Adds> adds;
...

Adds is another custom class with all getters/setters declared, same as Item. I can directly save the adds map with setvalue, but when i try to setvalue() i keep getting the following error.

Caused by: com.google.firebase.database.DatabaseException: Maps with non-string keys are not supported

DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("test").setValue(p);

This is what i'm trying, of course p is the instance of Item. Is there a way to directly save the object like this? Or do i need to do another setvalue for the map?

Here are the 2 classes

public class Item {
public String id;
public String name;
public double price;
public Map<String, Adds> adds;

public Item() {

}

public Item(String name, double price) {
    this.name = name;
    this.price = price;
    adds = new HashMap<>();
}

@Exclude
public void addAdds(Adds adds){
    this.adds.put(adds.getId(), adds);
}

@Exclude
public void removeAdds(Adds adds){
    this.adds.remove(adds);
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public double getPrice() {
    return price;
}

@Exclude
public void setPrice(double price) {
    this.price = price;
}

public Map<String, Adds> getAdds() {
    return adds;
}

public void setAdds(HashMap<String, Adds> adds) {
    this.adds = adds;
}

}

And here is Adds

public class Adds {
public String id;
public String name;
public double plus;
public double minus;
private boolean primary = false;


public Adds() {

}

public Adds(String name) {

}

public Adds(String id, String name, double plus, double minus) {

    this.id = id;
    this.name = name;
    this.plus = plus;
    this.minus = minus;
}


public String getId() {
    return id;
}

public String getName() {
    return name;
}

public double getPlus() {
    return plus;
}

public double getMinus() {
    return minus;
}

private boolean isPrimary() {
    return primary;
}

public void setName(String name) {
    this.name = name;
}

@Override
public String toString() {
    return "Adds{" +
            "id='" + id + '\'' +
            ", name='" + name + '\'' +
            ", plus=" + plus +
            ", minus=" + minus +
            ", primary=" + primary +
            '}';
}
}

Upvotes: 0

Views: 7415

Answers (2)

Piotr Z
Piotr Z

Reputation: 874

@Test
public void myFirebaseTest2(){
    Adds adds = new Adds();
    adds.setName("adds test name");

    Item item = new Item();
    item.adds = new HashMap<>();
    //item.adds.put(null, adds);
    item.adds.put("uniquekey", adds);

    DatabaseReference mDatabase;
    mDatabase = FirebaseDatabase.getInstance().getReference();
    mDatabase.child("test").setValue(item);
}

commenting/uncommenting 5th line of the test method reproduces the DatabaseException and explains the problem:

most probably one of the keys in your "adds" map was null (unset)

Upvotes: 1

Piotr Z
Piotr Z

Reputation: 874

It seems to me that in "Adds" class you might have a Map-type property like Map where K is not type String

Can you share how the Adds class look like? At least its properties (fields)

//edit

I just wrote an instrumented androidTest (important: ran on the device to have real android environment):

@Test
public void myFirebaseTest(){
    Adds adds = new Adds();
  //adds.id = "id";
    adds.setName("adds test name");

    Item item = new Item("test name", 2.34);
    item.addAdds(adds);
    DatabaseReference mDatabase;
    mDatabase = FirebaseDatabase.getInstance().getReference();
    mDatabase.child("test").setValue(item);
}

with below line commented out I was able to reproduce your error

//adds.id = "id";

uncommenting it solved the problem

it was because in "Item" class you have:

public void addAdds(Adds adds){
      this.adds.put(adds.getId(), adds);
}

where "adds" is a Java Map, and what you did was map.put(key, value) ,

but adds.id (the key) was unset (null) and caused the mentioned DatabaseException

Upvotes: 1

Related Questions