shlomi
shlomi

Reputation: 35

Firebase Error: Expected a List, but got a class java.util.HashMap

I have an object called Garage and once I first declare him, it has 4 parameters: garageName,garageId, garageCoordinatorPhone,garageProducts. I upload it to firebase. After some time I update the garage parameter in firebase: garageStocks. When I try getting the data out back to Garage class, I get the exeption:

com.google.firebase.database.DatabaseException: Expected a List while deserializing, but got a class java.util.HashMap

I looked at an almost exact question like this at: Expected a List while deserializing, but got a class java.util.HashMap

But it's answers doesn't make sense to me... I have been able to get the values even with lists of objects(see garageProducts).

GaragesActivity:

public class GaragesActivity extends AppCompatActivity {

    ArrayList<String> garages = new ArrayList<>();
    DatabaseReference dbReference = FirebaseDatabase.getInstance().getReference();
    RecyclerView rvGarages;
    Button tvGarageEdit;
    TextView tvGarageCoordinator;
    User selectedGarageCoordinator = null;
    boolean isEditable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_garages);

        
        //defines the widgets
        rvGarages = findViewById(R.id.rvGarages);
        tvGarageEdit = findViewById(R.id.tvGarageEdit);

        refreshAllGarages();

        //defines and sets the toolbar in place.
        Toolbar toolbar = findViewById(R.id.app_bar);
        setSupportActionBar(toolbar);

        //defines the back button at the top corner
        ActionBar ab = getSupportActionBar();
        if(ab != null)
            ab.setDisplayHomeAsUpEnabled(true);


        tvGarageEdit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //the opposite every press
                if (isEditable){
                    isEditable = false;
                    tvGarageEdit.setBackgroundColor(getResources().getColor(R.color.colorWritingImportant));
                }else{
                    isEditable = true;
                    tvGarageEdit.setBackgroundColor(getResources().getColor(R.color.colorLimeGreen));
                }
            }
        });
    }
    
    private void refreshAllGarages() {
        //reset
        garages.clear();
        GaragesAdapter myAdapter = new GaragesAdapter(GaragesActivity.this, garages);
        rvGarages.setAdapter(myAdapter);

        final Dialog myDialog = new Dialog(GaragesActivity.this);
        myDialog.setContentView(R.layout.dialog_progress);
        if(myDialog.getWindow() != null)
            myDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

        TextView tvAction = myDialog.findViewById(R.id.tvAction);
        tvAction.setText("טוען...");
        myDialog.show();

        // Read from the database
        Query q = dbReference.child("מחסנים").orderByKey();
        q.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                for (DataSnapshot AllGarages : dataSnapshot.getChildren()) //gets the list of Garages
                {
                    Garage g = AllGarages.getValue(Garage.class);
                    if(g.getGarageName() != null)
                        garages.add(g.getGarageName());
                }
                GaragesAdapter myAdapter = new GaragesAdapter(GaragesActivity.this, garages);
                rvGarages.setLayoutManager(new GridLayoutManager(GaragesActivity.this,4));
                myDialog.dismiss();
                rvGarages.setAdapter(myAdapter);
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {
                throw databaseError.toException(); //Don't ignore errors
            }
        });

    }
}

Garage class:

public class Garage {

    private String garageName;
    private String garageId;
    private String garageCoordinatorPhone;
    private ArrayList<Product> garageProducts;
    private ArrayList<Product> borrowedProducts;
    private ArrayList<Product> damagedProducts;
    private ArrayList<Product> missingProducts;
    private ArrayList<Stock> garageStocks;

    public Garage(){}

    public Garage(String garageName, String garageCoordinatorPhone, String garageId, ArrayList<Product> garageProducts){
        this.garageProducts = garageProducts;
        this.garageName = garageName;
        this.garageCoordinatorPhone = garageCoordinatorPhone;
        this.garageId = garageId;
    }

    public Garage(String garageName, String garageCoordinatorPhone, String garageId, ArrayList<Product> garageProducts, ArrayList<Stock> garageStocks){
        this.garageProducts = garageProducts;
        this.garageStocks = garageStocks;
        this.garageName = garageName;
        this.garageCoordinatorPhone = garageCoordinatorPhone;
        this.garageId = garageId;
    }

    public Garage(String garageName, String garageCoordinatorPhone, String garageId, ArrayList<Product> garageProducts, ArrayList<Stock> garageStocks, ArrayList<Product> borrowedProducts){
        this.garageProducts = garageProducts;
        this.garageStocks = garageStocks;
        this.garageName = garageName;
        this.garageCoordinatorPhone = garageCoordinatorPhone;
        this.garageId = garageId;
        this.borrowedProducts = borrowedProducts;
    }

    public Garage(String garageName, String garageCoordinatorPhone, String garageId, ArrayList<Product> garageProducts, ArrayList<Stock> garageStocks, ArrayList<Product> borrowedProducts, ArrayList<Product> damagedProducts, ArrayList<Product> missingProducts){
        this.garageProducts = garageProducts;
        this.garageStocks = garageStocks;
        this.garageName = garageName;
        this.garageCoordinatorPhone = garageCoordinatorPhone;
        this.garageId = garageId;
        this.borrowedProducts = borrowedProducts;
        this.damagedProducts = damagedProducts;
        this.missingProducts = missingProducts;
    }
}

Firebase:

{
  "173baaa74c0" : {
    "garageCoordinatorPhone" : "0523122548",
    "garageId" : "173baaa74c0",
    "garageName" : "רעננה מרכז",
    "garageProducts" : [ {
      "description" : "אורך 1.7 מטר",
      "productAmount" : 5,
      "productCategory" : "בנייה מחנאית",
      "productId" : 201,
      "productName" : "בזנט"
    }, {
      "description" : "נפח 500 סמ'ק",
      "productAmount" : 5,
      "productCategory" : "כיבוי אש",
      "productId" : 402,
      "productName" : "מטפים תקינים"
    }, {
      "description" : "אורך 30 ס'מ",
      "productAmount" : 4,
      "productCategory" : "כלי עבודה",
      "productId" : 506,
      "productName" : "שפכטל"
    }, {
      "description" : "אורך 30 ס'מ",
      "productAmount" : 1,
      "productCategory" : "חשמל",
      "productId" : 323,
      "productName" : "DI"
    }, {
      "description" : "סיר מתכת לטיולים, קוטר 15 ס'מ",
      "productAmount" : 7,
      "productCategory" : "בישול",
      "productId" : 127,
      "productName" : "סיר בינוני"
    }, {
      "description" : "",
      "productAmount" : 1,
      "productCategory" : "חשמל",
      "productId" : 309,
      "productName" : "מיקרופון"
    } ],
    "garageStocks" : {
      "1610831472776" : {
        "stockFillerPhone" : "0544926410",
        "stockId" : 1610831472776,
        "stockProducts" : [ {
          "description" : "אורך 1.7 מטר",
          "productAmount" : 5,
          "productCategory" : "בנייה מחנאית",
          "productId" : 201,
          "productName" : "בזנט"
        }, {
          "description" : "נפח 500 סמ'ק",
          "productAmount" : 5,
          "productCategory" : "כיבוי אש",
          "productId" : 402,
          "productName" : "מטפים תקינים"
        }, {
          "description" : "אורך 30 ס'מ",
          "productAmount" : 4,
          "productCategory" : "כלי עבודה",
          "productId" : 506,
          "productName" : "שפכטל"
        }, {
          "description" : "אורך 30 ס'מ",
          "productAmount" : 1,
          "productCategory" : "חשמל",
          "productId" : 323,
          "productName" : "DI"
        }, {
          "description" : "סיר מתכת לטיולים, קוטר 15 ס'מ",
          "productAmount" : 7,
          "productCategory" : "בישול",
          "productId" : 127,
          "productName" : "סיר בינוני"
        }, {
          "description" : "",
          "productAmount" : 1,
          "productCategory" : "חשמל",
          "productId" : 309,
          "productName" : "מיקרופון"
        } ]
      }
    }
  },
  "1740c8d4920" : {
    "garageCoordinatorPhone" : "0544926411",
    "garageId" : "1740c8d4920",
    "garageName" : "אשדוד ט'ו",
    "garageProducts" : [ {
      "description" : "",
      "productAmount" : 2,
      "productCategory" : "שונות",
      "productHome" : "173baaa74c0",
      "productId" : 1102,
      "productName" : "דרבוקות גדולות"
    }, {
      "description" : "נפח 500 סמ'ק",
      "productAmount" : 2,
      "productCategory" : "כיבוי אש",
      "productHome" : "173baaa74c0",
      "productId" : 402,
      "productName" : "מטפים תקינים"
    } ]
  },
  "174534895e0" : {
    "borrowedProducts" : {
      "5f66189e 207aeaca" : [ {
        "description" : "סיר מתכת לטיולים, קוטר 15 ס'מ",
        "productAmount" : 1,
        "productCategory" : "בישול",
        "productHome" : "173baaa74c0",
        "productId" : 127,
        "productName" : "סיר בינוני"
      } ]
    },
    "garageCoordinatorPhone" : "0544926410",
    "garageId" : "174534895e0",
    "garageName" : "הכפתור",
    "garageProducts" : [ {
      "description" : "אורך 1.7 מטר",
      "productAmount" : 23,
      "productCategory" : "בנייה מחנאית",
      "productHome" : "173baaa74c0",
      "productId" : 201,
      "productName" : "בזנט"
    }, {
      "description" : "",
      "productAmount" : 2,
      "productCategory" : "שונות",
      "productHome" : "173baaa74c0",
      "productId" : 1102,
      "productName" : "דרבוקות גדולות"
    }, {
      "description" : "נפח 500 סמ'ק",
      "productAmount" : 1,
      "productCategory" : "כיבוי אש",
      "productHome" : "173baaa74c0",
      "productId" : 402,
      "productName" : "מטפים תקינים"
    } ]
  }
}
enter code here

Upvotes: 0

Views: 800

Answers (2)

Miftah Classifieds
Miftah Classifieds

Reputation: 291

the problem persists even if you change the hashmap to list. explanation: if on item of list is removed the realtime database reconsider the list as a hashmap and then throws the error. so I think this is a problem of firebase and need to be recovered by their team!

Upvotes: 1

kungpaogao
kungpaogao

Reputation: 84

Based on your Firebase JSON, it looks like you're storing an object with fields for each Stock in garageStocks instead of a list like your Garage class expects.

For example, you have:

"garageStocks" : {
  "stockObject1": { ... },
  "stockObject2": { ... },
  ...
}

However, your Garage class expects a list: private ArrayList<Stock> garageStocks;, which should be the following in JSON:

"garageStocks": [
  { stock object 1 },
  { stock object 2 },
  ...
]

That's why you're getting the error that it expects a list and is getting a map instead.

To fix this, you have a couple of options:

  1. Change the way you push data to Firebase to make sure you're pushing a list
  2. Change the type of garageStocks to a HashMap

I don't know what you're currently doing for option 1, but you seem to be doing the correct thing for the product lists (ArrayList<Product>) in the Garage class, so that could be a good place to look.

Hope this helps!

Upvotes: 2

Related Questions