Faget Thomas
Faget Thomas

Reputation: 77

Error when getting an object from DataSnapshot

I am implementing a database with Firebase for an android application.

I present 2 beans : User.class and Address.class, using by the app :

@IgnoreExtraProperties
public class User {

    @Exclude
    private String idAccount;
    private String firstname;
    private String lastname;
    private String pseudo;
    private Address address;
    private List<Qualification> qualification;
    private boolean isWorker;

    // Constructors + getters + setters

}

and

public class Address {

    private String houseNumber;
    private String street;
    private String city;
    private String zip;
    private String country;

    // Constructors + getters + setters

}

So, I can add an user in the database with usersRef.child(idUser).setValue(user), where usersRef is my reference of the users in the database (See result)

I can also get the user with a ValueEventListener:

        Query query = usersRef.child(idUser);
        query.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                User user = dataSnapshot.getValue(User.class);
                result.call(user);
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                throw databaseError.toException();
            }
        });

(See result)

So, for now all is working !

But, if I try to put a ChildEventListener on my usersRef, I have a crash :

 usersRef.addChildEventListener(new ChildEventListener() {

            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {

                User user = dataSnapshot.getValue(User.class); // crash here
                }
            }

            ...

}

FATAL EXCEPTION: PID: 29470 com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type ca.uqac.sosdoit.data.Address at com.google.android.gms.internal.zzear.zzb(Unknown Source) at com.google.android.gms.internal.zzear.zza(Unknown Source) at com.google.android.gms.internal.zzear.zzb(Unknown Source) at com.google.android.gms.internal.zzeas.zze(Unknown Source) at com.google.android.gms.internal.zzear.zzb(Unknown Source) at com.google.android.gms.internal.zzear.zza(Unknown Source) at com.google.firebase.database.DataSnapshot.getValue(Unknown Source) at ca.uqac.sosdoit.database.DatabaseManager$1.onChildAdded(DatabaseManager.java:68) at com.google.android.gms.internal.zzdri.zza(Unknown Source) at com.google.android.gms.internal.zzdwu.zzbvb(Unknown Source) at com.google.android.gms.internal.zzdxa.run(Unknown Source) at android.os.Handler.handleCallback(Handler.java:808) at android.os.Handler.dispatchMessage(Handler.java:103) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:5292) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640) at dalvik.system.NativeStart.main(Native Method)

And I absolutely don't know why

Upvotes: 1

Views: 2428

Answers (2)

Venkata Narayana
Venkata Narayana

Reputation: 1697

Seems like one(or some) of the User nodes has an address field of type String. Surround it with try catch and log both the exception and key of the node to find the culprit(s).

 usersRef.addChildEventListener(new ChildEventListener() {

        @Override
         public void onChildAdded(DataSnapshot dataSnapshot, String s) {

           try{
                User user = dataSnapshot.getValue(User.class);
            }
            catch(DatabaseException e){
                //Log the exception and the key 
                dataSnapshot.getKey();
            }
         }

            ...

}

Upvotes: 1

Grimthorr
Grimthorr

Reputation: 6926

The error relates to Firebase trying to marshal the address value under one of the user nodes into an Address class instance.

The address value in the database should match your class Address, but one of them is a string which can't be converted to an Address instance.

If the address value is supposed to be a string, you'll need to change the type of the address field on the User class to String:

private String address;

Otherwise, you'll need to check each node under user in your database for any that incorrectly have a string for the address value.

Upvotes: 1

Related Questions