android – Firebase: How to ignore validate type of fields for an object model?-ThrowExceptions

Exception or error:

My android application is crashing on start up, because of a small error in my back-end side which is in firebase. A document in my firestore database has a field in which an Image object (id and url) is expected but for some reason it’s stored as a long in the database.

I get this error:

 java.lang.RuntimeException: Could not deserialize object. Can't convert object of type java.lang.Long to type com..data.entity.gps.tracker.ImageEntity

My ImageEntity class:

public class ImageEntity {
    private int id;
    private String image_id;


    public String getImage_id() {
        return image_id;
    }

    public void setImage_id(String image_id) {
        this.image_id = image_id;
    }

    public int getId() {
        return id;
    }

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

I can’t just exclude the cover ImageEntity object, it’s an integral part of my app, how can I add a validation step to check if the cover object is a valid object and not a long?

This is where the crash happens:

public List<Model> mapList(QuerySnapshot querySnapshot) {
    List<Model> list = new ArrayList<>();
    for (QueryDocumentSnapshot queryDocumentSnapshot : querySnapshot) {
        Model model = map(queryDocumentSnapshot);
        long id = ((Release) model).getId();
        if (!addedReleasesIDs.contains(id)) {
            list.add(model);
            addedReleasesIDs.add(id);
        }
    }
    return list;
}

public Model map(QueryDocumentSnapshot queryDocumentSnapshot) {
    // Auto serialization
    Entity entity = queryDocumentSnapshot.toObject(getEntityClass()); // CRASH HERE
    return map(entity);
}
How to solve:

If you need to take control over the deserializaition of a document snapshot, you should access its fields as a Map<String, Object> using getData() instead of using the Firebase SDKs internal mapper.

Map<String, Object> data = (Map<String, Object>) queryDocumentSnapshot.getData();

With this, you can now get() the individual fields by name out of the data map, check their types, and convert them to whatever other type you want for your model object.

This is also faster in terms of performance than using toObject because it doesn’t have to use Java reflection.

Leave a Reply

Your email address will not be published. Required fields are marked *