RealDEV
RealDEV

Reputation: 131

Android Firebase get List Data

enter image description here

I am trying to get movies list info in my application.

MainActivity

database = FirebaseDatabase.getInstance().getReference();
        databaseMovies= database.child("Movies");

        DatabaseReference databaseReference=databaseMovies;
        databaseReference.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                for (DataSnapshot postSnapshot:dataSnapshot.getChildren()){
                    SingleItem singleItem=postSnapshot.getValue(SingleItem.class);
                    items.add(singleItem);
                }

                Toast.makeText(MainActivity.this,items.get(0).getTitle(),Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

SingleItem

public class SingleItem {

    private String image;
    private String link;
    private String title;
    private String views;

    public SingleItem(String image, String link, String title, String views) {
        this.image = image;
        this.link = link;
        this.title = title;
        this.views = views;
    }

    public String getImage() {
        return image;
    }

    public String getLink() {
        return link;
    }

    public String getTitle() {
        return title;
    }

    public String getViews() {
        return views;
    }
}

Application crashes, The object class I made don't read the info right. I want to store a list of movie object and each object contains the movie info.

enter image description here

Upvotes: 1

Views: 2998

Answers (3)

Alex Mamo
Alex Mamo

Reputation: 138824

You need to add the public no-argument constructor need for Firebase in your SingleItem class. Remember, when the Firebase Realtime Database SDK deserializes objects coming from the database, it requires that any objects in use to have a public no-argument constructor that it can use to instantiate the object. Fields in the objects are set by using the public setter methods or direct access to public members.

If you don't use public no-argument constructor, the SDK doesn't really know how to create an instance of it. In fact, most serialization libraries will have the same requirement.

Your class should look like this:

public class SingleItem {

    @PropertyName("Image")
    private String image;
    @PropertyName("Link")
    private String link;
    @PropertyName("Title")
    private String title;
    @PropertyName("Views")
    private String views;

    public SingleItem() {} //no-argument constructor

    public SingleItem(String image, String link, String title, String views) {
        this.image = image;
        this.link = link;
        this.title = title;
        this.views = views;
    }

    public String getImage() {
        return image;
    }

    public String getLink() {
        return link;
    }

    public String getTitle() {
        return title;
    }

    public String getViews() {
        return views;
    }
}

See also the added annotations. I have added this annotations because of the difference between your fields from your model class which contains first letter lowercase and the actual key from the database which contains first letter uppercase.

To ge the data from your database, please use the following code:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference moviesRef = rootRef.child("movies");
ValueEventListener eventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            String Image = ds.child("Image").getValue(String.class);
            String Link = ds.child("Link").getValue(String.class);
            String Title = ds.child("Title").getValue(String.class);
            int Views = ds.child("Image").getValue(Integer.class);
            Log.d("TAG", Image + "/" + Link + "/" + Title + "/" + Views);
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}
};
moviesRef.addListenerForSingleValueEvent(eventListener);

Upvotes: 1

silverFoxA
silverFoxA

Reputation: 4659

The error console says it all You are missing a no argument constructor.

You may want to use Json2Schema to make the work much more easier. As you haven't added the serializable elements to your class which might cause you trouble later on. ex: When you want to serialize the class you have to implement Serializable also SerializeName & Expose annotation GSON

Thus change your Singleton class to this

public class SingleItem implements Serializable{

@SerializedName("image")
@Expose
private String image;
@SerializedName("link")
@Expose
private String link;
@SerializedName("title")
@Expose
private String title;
@SerializedName("views")
@Expose
private String views;

//NO ARGUMENT CONSTRUCTOR
SingleItem(){}

public SingleItem(String image, String link, String title, String views) {
    this.image = image;
    this.link = link;
    this.title = title;
    this.views = views;
}

public String getImage() {
    return image;
}

public String getLink() {
    return link;
}

public String getTitle() {
    return title;
}

public String getViews() {
    return views;
}
}

Upvotes: 0

Cătălin Florescu
Cătălin Florescu

Reputation: 5158

public no-argument constructor means that you need a constructor with no passing data in it

public SingleItem() {
    // in order to avoid null values, init your data
    this.image = "";
    this.link = "";
    this.title = "";
    this.views = "";
}

Also, i see in your list of data from firebase data that your key is first letter uppercase. In this case, you should use @PropertyName annotation. Ex:

@PropertyName("Image")
public String image;

@PropertyName("Link")
public String link;

//etc

Since you have private variables, you can annotate methods and have private variables:

@PropertyName("Image")
public String getImage() {
    return image;
}

From documatation, you can annotate private variables also, but for me is not working. You can try it.

Upvotes: 2

Related Questions