RamithDR
RamithDR

Reputation: 2213

Firebase dataSnapshot isn't converted to custom Java object

I'm facing an issue trying to map the JSON data retrieved from Firebase database to a custom Java class in my project. I'm trying to retrieve all children nodes under Restaurants node.

Firebase data structure for Restaurants node:

"Restaurants" : {
    "ZyZnmC3xC39Jv1oVVdXbQdyCOcTQ" : {
      "restaurantContactNo" : "222922943",
      "restaurantImgUrl" : "https://firebasestorage.googleapis.com/...",
      "restaurantWebsite" : "www.bubbleme.com",
      "restaurant_address" : "40/1/1",
      "restaurant_category" : "coffee",
      "restaurant_latitude" : "6.983489f",
      "restaurant_longitude" : "79.932736f",
      "restaurant_name" : "Bubble Me Bubble Tea",
      "restaurant_rating" : 4.5
    }

Here's how I'm trying to create an object out of the retrieved data:

mDatabaseRef = FirebaseDatabase.getInstance().getReference().child("Restaurants");
            mDatabaseRef.addValueEventListener(new ValueEventListener() {
                        @Override
                        public void onDataChange(DataSnapshot dataSnapshot) {

                            if(dataSnapshot.exists()){

                                for(DataSnapshot data : dataSnapshot.getChildren()) {

                                    Restaurants res = data.getValue(Restaurants.class);


    ......

But res is always null, I printed the datasnapshot to the console and the data is all there in JSON format:

{ZyZnmC3xC39Jv1oVVdXbQdyCOcTQ={restaurant_rating=4.5, restaurant_longitude=79.932736f, restaurant_category=coffee, restaurantContactNo=0112922943, restaurant_address=40/1/1, restaurantImgUrl=https://firebasestorage.googleapis.com/.., restaurant_name=Bubble Me Bubble Tea, restaurant_latitude=6.983489f, restaurantWebsite=www.bubbleme.com}}

Restaurants Java Class:

public class Restaurants {

    private String restaurant_longitude;
    private String restaurant_latitude;
    private String restaurant_name;
    private String restaurant_address;
    private String restaurantImgUrl;
    private String restaurant_category;
    private String restaurant_rating;
    private String restaurantContactNo;
    private String restaurantWebsite;

    public Restaurants(){}


    public Restaurants(String restaurant_rating, String restaurant_longitude, String restaurant_category, String restaurantContactNo,
                       String restaurant_address, String restaurantImgUrl, String restaurant_name, String restaurant_latitude, String restaurantWebsite) {

        this.restaurant_rating = restaurant_rating;
        this.restaurant_longitude = restaurant_longitude;
        this.restaurant_category = restaurant_category;
        this.restaurantContactNo = restaurantContactNo;
        this.restaurant_address = restaurant_address;
        this.restaurantImgUrl = restaurantImgUrl;
        this.restaurant_name = restaurant_name;
        this.restaurant_latitude = restaurant_latitude;
        this.restaurantWebsite = restaurantWebsite;

    }

    public String getRestaurantWebsite() {
        return restaurantWebsite;
    }

    public String getRestaurantContactNo() {
        return restaurantContactNo;
    }

    public String getRestaurantRating() {
        return restaurant_rating;
    }

    public String getRestaurantCategory() {
        return restaurant_category;
    }

    public String getRestaurantImgUrl() {
        return restaurantImgUrl;
    }

    public String getRestaurantAddress() {
        return restaurant_address;
    }

    public String getRestaurantTitle() {
        return restaurant_name;
    }

    public String getRestaurantLatitude() {
        return restaurant_latitude;
    }

    public String getRestaurantLongitude() {
        return restaurant_longitude;
    }

}

I've tried many times using ValueEventListner, ChildValueEventListner and ListnerForSingleChild but I simply cannot get it to work, I know I'm really close since the datasnapshot retrieves the data but I believe mapping the data to the Restaurants object is where the problem lies.

Any help regarding this would be helpful.

----ISSUE FIXED----

I finally solved it by deleting my Restaurants Java class and re-implementing the class with the required members. It's strange, the new class is exactly the same as the last one but somehow it works. Maybe because my old class was implemented a long time before I integrated Firebase into my project, I cannot think of a sensible reason how it worked.

Special thanks to Doug, Lewis and Rosário for their valuable feedback.

Upvotes: 1

Views: 1445

Answers (1)

Lewis McGeary
Lewis McGeary

Reputation: 7922

As you have mentioned in comments that ProGuard is enabled that is a possible cause of the problem.

See the guidance here on configuring ProGuard, which suggests adding rules to proguard-rules.pro:

# Add this global rule
-keepattributes Signature

# This rule will properly ProGuard all the model classes in
# the package com.yourcompany.models. Modify to fit the structure
# of your app.
-keepclassmembers class com.yourcompany.models.** {
  *;
}

Put all your Java model classes for Firebase into a package and change the keepclassmembers rule to match your app. Essentially because you are not calling these fields in your code, ProGuard can assume they can be removed, so when Firebase tries to use them it fails.

Upvotes: 2

Related Questions