Reputation: 723
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
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
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