Could not deserialize object. Failed to convert value of type java.util.Date to String

Viewed 3430

I'm a complete novice in the Android world. I'm trying to read data from firebase cloud firestore at real time. I have uploaded objects of Tree.java class 4 of whose attributes are Timestamps as can see in the firebase console screenshot and Tree.java class code.

firebase console - Cloudfirestore

Tree.java

import com.google.firebase.Timestamp;

import java.util.HashMap;
import java.util.Map;

import static com.example.malayishant.greencare.AddTree.DOP;
import static com.example.malayishant.greencare.AddTree.ID;
import static com.example.malayishant.greencare.AddTree.MANURE;
import static com.example.malayishant.greencare.AddTree.WATER;
import static com.example.malayishant.greencare.AddTree.WEED;

public class Tree {

    private String id;
    private Timestamp dop;
    //private GeoPoint geo;
    private Timestamp water;
    private Timestamp weed;
    private Timestamp manure;

    public Tree() {
    }

    public Tree(String id, Timestamp dop, Timestamp water,
                Timestamp weed, Timestamp manure) {
        this.id = id;
        this.dop = dop;

        this.water = water;
        this.weed = weed;
        this.manure = manure;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Timestamp getDop() {
        return dop;
    }

    public void setDop(Timestamp dop) {
        this.dop = dop;
    }

    public Timestamp getWater() {
        return water;
    }

    public void setWater(Timestamp water) {
        this.water = water;
    }

    public Timestamp getWeed() {
        return weed;
    }

    public void setWeed(String name) {
        this.weed = weed;
    }

    public Timestamp getManure() {
        return manure;
    }

    public void setManure(Timestamp manure) {
        this.manure = manure;
    }

}

The follwing code is used to upload data to cloud fire store.

import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.Timestamp;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.FirebaseFirestore;

import java.util.HashMap;
import java.util.Map;

public class AddTree extends AppCompatActivity {
public static final String ID = "id";
public static final String DOP = "dop";

public static final String WATER = "water";
public static final String WEED = "weed";
public static final String MANURE = "manure";

// Access a Cloud Firestore instance from your Activity

FirebaseFirestore db = FirebaseFirestore.getInstance();
private Button mButton;

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

    mButton = findViewById(R.id.buttonAdd);
    mButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            // your handler code here
            uploadTree();
        }
    });

}

public void uploadTree() {
    EditText IdEditText = findViewById(R.id.IdeditText);
    String id = IdEditText.getText().toString();
    // Timestamp dop = Timestamp.now();
    //geo
    if (id.isEmpty()) {
        return;
    }
    Map<String, Object> tree = new HashMap<String, Object>();
    tree.put(ID, id);
    tree.put(DOP, Timestamp.now());
    tree.put(WATER, Timestamp.now());
    tree.put(WEED, Timestamp.now());
    tree.put(MANURE, Timestamp.now());
    db.collection("trees")
            .add(tree)
            .addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
                @Override
                public void onSuccess(DocumentReference documentReference) {
                    // Log.d(TAG, "DocumentSnapshot added with ID: " + documentReference.getId());
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                     Log.w(TAG, "Error adding document", e);
                }
            });


}

}

The following code I'm using to get data from the cloud firestore. the runtume error occurring in this code snippet as marked in the code snippet. I'm getting a "java.lang.RuntimeException: Could not deserialize object. Failed to convert value of type java.util.Date to String (found in field 'weed')" when i run the code.

firestoreDB.collection("trees")
                .get()
                .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
                    @Override
                    public void onComplete(@NonNull Task<QuerySnapshot> task) {
                        if (task.isSuccessful()) {
                           List<Tree> treeList = new ArrayList<>();


                            for (DocumentSnapshot doc : task.getResult()) {
                                Tree tree = doc.toObject(Tree.class);/*this line causing the error*/

                                treeList.add(tree);
                            }

                            mAdapter = new TreeDbAdapter(treeList, getContext(), firestoreDB);
                            RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getContext());
                            recyclerView.setLayoutManager(mLayoutManager);
                            recyclerView.setItemAnimator(new DefaultItemAnimator());
                            recyclerView.setAdapter(mAdapter);
                        } else {
                            Log.d(TAG, "Error getting documents: ", task.getException());

                        }
                    }
                });

Errors I'm getting

11-09 20:58:46.182 10665-10665/com.example.malayishant.greencare E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.malayishant.greencare, PID: 10665
    java.lang.RuntimeException: Could not deserialize object. Failed to convert value of type java.util.Date to String (found in field 'weed')
        at com.google.firebase.firestore.util.CustomClassMapper.deserializeError(com.google.firebase:firebase-firestore@@17.1.2:524)
        at com.google.firebase.firestore.util.CustomClassMapper.convertString(com.google.firebase:firebase-firestore@@17.1.2:445)
        at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-firestore@@17.1.2:217)
        at com.google.firebase.firestore.util.CustomClassMapper.deserializeToType(com.google.firebase:firebase-firestore@@17.1.2:180)
        at com.google.firebase.firestore.util.CustomClassMapper.access$200(com.google.firebase:firebase-firestore@@17.1.2:53)
        at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(com.google.firebase:firebase-firestore@@17.1.2:700)
        at com.google.firebase.firestore.util.CustomClassMapper$BeanMapper.deserialize(com.google.firebase:firebase-firestore@@17.1.2:674)
        at com.google.firebase.firestore.util.CustomClassMapper.convertBean(com.google.firebase:firebase-firestore@@17.1.2:503)
        at com.google.firebase.firestore.util.CustomClassMapper.deserializeToClass(com.google.firebase:firebase-firestore@@17.1.2:242)
        at com.google.firebase.firestore.util.CustomClassMapper.convertToCustomClass(com.google.firebase:firebase-firestore@@17.1.2:97)
        at com.google.firebase.firestore.DocumentSnapshot.toObject(com.google.firebase:firebase-firestore@@17.1.2:203)
        at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(com.google.firebase:firebase-firestore@@17.1.2:121)
        at com.google.firebase.firestore.DocumentSnapshot.toObject(com.google.firebase:firebase-firestore@@17.1.2:183)
        at com.google.firebase.firestore.QueryDocumentSnapshot.toObject(com.google.firebase:firebase-firestore@@17.1.2:101)
        at com.example.malayishant.greencare.FragmentDb$1.onEvent(FragmentDb.java:64)
        at com.example.malayishant.greencare.FragmentDb$1.onEvent(FragmentDb.java:52)
        at com.google.firebase.firestore.Query.lambda$addSnapshotListenerInternal$2(com.google.firebase:firebase-firestore@@17.1.2:882)
        at com.google.firebase.firestore.Query$$Lambda$3.onEvent(com.google.firebase:firebase-firestore@@17.1.2)
        at com.google.firebase.firestore.util.ExecutorEventListener.lambda$onEvent$0(com.google.firebase:firebase-firestore@@17.1.2:42)
        at com.google.firebase.firestore.util.ExecutorEventListener$$Lambda$1.run(com.google.firebase:firebase-firestore@@17.1.2)
        at android.os.Handler.handleCallback(Handler.java:742)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5602)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:774)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
1 Answers

You are getting the following error:

java.lang.RuntimeException: Could not deserialize object. Failed to convert value of type java.util.Date to String (found in field 'weed')

Because in your Tree class the argument of your setWeed() method is of type String and not Timestamp.

To solve this, please change the following lines of code:

public void setWeed(String name) {
    this.weed = weed;
}

to

public void setWeed(Timestamp weed) {
    this.weed = weed;
}
Related