Jackdaw
Jackdaw

Reputation: 723

Class android.location.Location does not define a no-argument constructor

I've been trying to simply push and read a class with two variables, a String and a Location, to firebase and I've been getting this error.

**com.google.firebase.database.DatabaseException: Class android.location.Location does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped.
                                                                            at com.google.android.gms.internal.zzeas.zze(Unknown Source:51)
                                                                            at com.google.android.gms.internal.zzear.zzb(Unknown Source:772)
                                                                            at com.google.android.gms.internal.zzear.zza(Unknown Source:312)
                                                                            at com.google.android.gms.internal.zzear.zzb(Unknown Source:0)
                                                                            at com.google.android.gms.internal.zzeas.zze(Unknown Source:209)
                                                                            at com.google.android.gms.internal.zzear.zzb(Unknown Source:772)
                                                                            at com.google.android.gms.internal.zzear.zza(Unknown Source:0)
                                                                            at com.google.firebase.database.DataSnapshot.getValue(Unknown Source:10)
                                                                            at com.example.vish.mcapp.Selection$2$1.onDataChange(Selection.java:85)
                                                                            at com.google.firebase.database.zzp.onDataChange(Unknown Source:7)
                                                                            at com.google.android.gms.internal.zzduz.zza(Unknown Source:13)
                                                                            at com.google.android.gms.internal.zzdwu.zzbvb(Unknown Source:2)
                                                                            at com.google.android.gms.internal.zzdxa.run(Unknown Source:65)
                                                                            at android.os.Handler.handleCallback(Handler.java:790)
                                                                            at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                            at android.os.Looper.loop(Looper.java:164)
                                                                            at android.app.ActivityThread.main(ActivityThread.java:6494)
                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)**

The class whose object I'm trying to push and read from firebase is below.

public class DeviceDetails {
   String nickname;
   Location location = new Location("Test");

    DeviceDetails()
     {
     }

     DeviceDetails(String nickname)
     {
     this.nickname = nickname;
     location.setLatitude(0.0);
     location.setLongitude(0.0);
     location.setTime(new Date().getTime());
     }

     DeviceDetails(String nickname, Location l)
     {
       this.nickname = nickname;
       location=l;
}

}

Pushing data into the Firebase works just fine. But I can't read it without running into the error above.

Code I've written for writing into firebase is : -

register.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            if(TextUtils.isEmpty(nickname.getText().toString()))
            {
                Toast.makeText(Selection.this, "Nickname can't be empty", Toast.LENGTH_SHORT).show();
                return;
            }
            else
            {
                Location loc = new Location("");
                loc.setLatitude(19.0);
                loc.setLongitude(29.5);
                loc.setTime(new Date().getTime());
                DeviceDetails newDevice = new DeviceDetails(nickname.getText().toString(), loc);
                mDatabase.child("Phones").child(nickname.getText().toString().trim().replaceAll("\\s","")).setValue(newDevice);
            }


        }
    });

Code I've written for reading from the Firebase and which I believe is the culprit is: -

retrieve.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            DatabaseReference database = FirebaseDatabase.getInstance().getReference();
            DatabaseReference myRef = database.child("Phones");
            myRef.child(nickToRetrieve.getText().toString().trim().replaceAll("\\s", "")).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    DeviceDetails dev = dataSnapshot.getValue(DeviceDetails.class);
                    double latitude = dev.location.getLatitude();
                    double longitude = dev.location.getLongitude();
                    String loc = "Latitude - " + latitude + " Longitude - " + longitude;
                    Toast.makeText(Selection.this, loc, Toast.LENGTH_LONG).show();
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });

Any help is greatly appreciated.

Upvotes: 4

Views: 3704

Answers (2)

Gk Mohammad Emon
Gk Mohammad Emon

Reputation: 6956

I just simply made a model by myself -

public class RequestLocation implements Parcelable {
    private  double lat;
    private double lon;

    protected RequestLocation(Parcel in) {
        lat = in.readDouble();
        lon = in.readDouble();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeDouble(lat);
        dest.writeDouble(lon);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Creator<RequestLocation> CREATOR = new Creator<>() {
        @Override
        public RequestLocation createFromParcel(Parcel in) {
            return new RequestLocation(in);
        }

        @Override
        public RequestLocation[] newArray(int size) {
            return new RequestLocation[size];
        }
    };

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }

    public double getLon() {
        return lon;
    }

    public void setLon(double lon) {
        this.lon = lon;
    }

    public RequestLocation(double lat, double lon) {
        this.lat = lat;
        this.lon = lon;
    }

   public RequestLocation(){
      
    }

}

And post it instead of framework's Location object.

Upvotes: 0

Doug Stevenson
Doug Stevenson

Reputation: 317692

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

Android's Location object dosen't have a public no-arg constructor, so the SDK doesn't really know how to create an instance of it. In fact, most serialization libraries will have the same requirement. So, instead of using Android's Location object, use one of your own, copying data in and out of it as needed.

Upvotes: 5

Related Questions