Error in fetching data from Firebase to RecyclerView. FATAL EXCEPTION: ... does not define a no-argument constructor

I have designed activity such that it fetches data from firebase Db and displays it in a recycler view but when I run it following error occurs

image

my code is

package com.example.android.indiandigitalschool;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;

import java.util.ArrayList;

public class ReceiveNews1 extends AppCompatActivity {
private RecyclerView rv;
private ArrayList<RvClass> list = new ArrayList<>() ;
private DatabaseReference demo;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_receive_news1);
    rv = findViewById(R.id.rv);
    rv.setHasFixedSize(true);
    rv.setLayoutManager(new LinearLayoutManager(this));

    demo= FirebaseDatabase.getInstance().getReference().child("IDS").child("News");
    demo.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for(DataSnapshot snapshot : dataSnapshot.getChildren()) {
            RvClass rvClass = snapshot.getValue(RvClass.class);//error occurs here
              list.add(rvClass);

            }
            CustomAdapter adapter = new CustomAdapter(ReceiveNews1.this,list);
            rv.setAdapter(adapter);

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });

}
}

My modal class(RvClass) code for handling data is

package com.example.android.indiandigitalschool;

public class RvClass {
private String title;
private String message;
private String time;

public RvClass(String title, String message, String time) {
    this.title = title;
    this.message = message;
    this.time = time;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

public String getMessage() {
    return message;
}

public void setMessage(String message) {
    this.message = message;
}

public String getTime() {
    return time;
}

public void setTime(String time) {
    this.time = time;
}
}

My firebase schema is

image

what is the mistake I am doing please help me in figuring out the bug? Thanks!


Solution 1:

You are getting the following error:

FATAL EXCEPTION: ... does not define a no-argument constructor

Because your RvClass class does not define a no-argument constructor.

JavaBeans require a no-argument constructor to be present.

In Java, when a class has no constructors at all, there is a default no-argument constructor automatically added by the compiler. The moment you define any constructor in the class, the default no-argument constructor goes away.

In your code, your RvClass class defines such a constructor that contains three arguments:

public RvClass(String title, String message, String time) {}

As long as this constructor is present and you don't define a no-argument constructor, that class will not have one.

To resolve this, you either remove that constructor from the class, or manually add a no-argument constructor as shown below:

public RvClass() {}

When the Firebase Realtime database SDK deserializes objects that are coming from the database, it requires that any objects in use, to have this constructor, so it can use it to instantiate the object. Fields in the objects are set by using public setter methods or direct access to public members.

If your RvClass class dosen't have a public no-arg constructor, the SDK doesn't really know how to create an instance of it. So it is mandatory to have it.

Also please note that setters and getter are not required. Setters are always optional because if there is no setter for a JSON property, the Firebase client will set the value directly onto the field. A constructor-with-arguments is also not required. Both are idiomatic and there are good cases to have classes without them. If you make the fields public, the getters are optional too.