0

I am getting the following error which is force-closing an activity (not the whole app):

com.google.firebase.database.DatabaseException: Class com.example.android.frapp.Notes does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped.

And it appears to state that the problem is here:

at com.example.android.frapp.NoteTakerActivity$3.onDataChange(NoteTakerActivity.java:93)

Below is the code from the Notes class:

public class Notes {

String notesId;
String notesTitle;
String notesType;

public Notes(String id, String mainNotes) {

}

public Notes(String notesId, String notesTitle, String notesType) {
    this.notesId = notesId;
    this.notesTitle = notesTitle;
    this.notesType = notesType;
}

public String getNotesId() {
    return notesId;
}

public String getNotesTitle() {

    return notesTitle;
}

public String getNotesType() {

    return notesType;
}
}

Below is the code from the NoteTakerActivity class:

public class NoteTakerActivity extends AppCompatActivity {

public static final String NOTES_TITLE = "notestitle";
public static final String NOTES_ID = "notesid";

EditText editNoteTitle;
Button addButton;
Spinner spinnerType;

DatabaseReference databaseNotes;

ListView listViewNotes;

List<Notes> notesList;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_note_taker);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    databaseNotes = FirebaseDatabase.getInstance().getReference("notes");

    editNoteTitle = (EditText) findViewById(R.id.noteTitleTxt);
    addButton = (Button) findViewById(R.id.addNoteBtn);
    spinnerType = (Spinner) findViewById(R.id.spinnerNoteType);

    listViewNotes = (ListView) findViewById(R.id.listViewNotes);

    notesList = new ArrayList<>();

    addButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            addNote();
        }
    });

    // for when a note title is clicked to open the next activity to write extensive notes
    listViewNotes.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
            Notes notes = notesList.get(i);
            Intent intent = new Intent(getApplicationContext(), AddMainNotesActivity.class);

            intent.putExtra(NOTES_ID, notes.getNotesId());
            intent.putExtra(NOTES_TITLE, notes.getNotesTitle());

            startActivity(intent);
        }
    });

}

@Override
protected void onStart() {
    super.onStart();

    // every time this method is executed it will fecth all the notes from the database and populate the list view
    databaseNotes.addValueEventListener(new ValueEventListener() {
        @Override
        // executed any time something is changed in the database
        public void onDataChange(DataSnapshot dataSnapshot) {

            notesList.clear();

            for (DataSnapshot notesSnapshot: dataSnapshot.getChildren()) {
                Notes notes = notesSnapshot.getValue(Notes.class); // this is line 93

                notesList.add(notes);
            }

            NotesList adapter = new NotesList(NoteTakerActivity.this, notesList);
            listViewNotes.setAdapter(adapter);
        }

        @Override
        // executed if there is some kind of error
        public void onCancelled(DatabaseError databaseError) {

        }
    });
}

private void addNote() {
    String title = editNoteTitle.getText().toString().trim();
    String type = spinnerType.getSelectedItem().toString();

    if (!TextUtils.isEmpty(title)) {

        String id = databaseNotes.push().getKey(); // id being created is unique every time

        Notes notes = new Notes(id, title, type);

        databaseNotes.child(id).setValue(notes); // to send data to database

        Toast.makeText(this, "Title added", Toast.LENGTH_SHORT).show();

        startActivity(getIntent());

    } else {
        Toast.makeText(this, "You must give the note a title", Toast.LENGTH_SHORT).show();
    }
}
}

I'm struggling to see the error. I feel that I have constructed everything correctly and can't understand or interpret correctly which error it is pointing to.
Can anyone assist me?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
emulus
  • 77
  • 1
  • 9

2 Answers2

2

The error message means you need to define a constructor for Notes class that takes no argument, like this:

public Notes() {

}

So you would have:

public class Notes {

 String notesId;
 String notesTitle;
 String notesType;

 public Notes(String id, String mainNotes) {

 }

 //a blank constructor//
 public Notes() {

 }

 public Notes(String notesId, String notesTitle, String notesType) {
   this.notesId = notesId;
   this.notesTitle = notesTitle;
   this.notesType = notesType;
 }

 public String getNotesId() {
   return notesId;
 }

 public String getNotesTitle() {

  return notesTitle;
 }

 public String getNotesType() {

  return notesType;
 }
}
Owen Cao
  • 7,955
  • 2
  • 27
  • 35
Demilade
  • 513
  • 2
  • 7
2

In addition to @omodemilade-bamgbose's answer, you need to know basic fundamental of Java constructor.

Java basically provides default constructor(which takes no arguments) by default even if you did not define it.

However, in your case, you've already defined another constructor which takes some arguments. That causes you make JVM understand that you are not using default constructor.

Hello world
  • 353
  • 3
  • 18