0

In my Android app, I'm trying to get a list of active users from my Firebase backend. The users are saved in Firebase as a Java class called UserActive that contains details about them.

I thought I did everything good, but I get an error and the app crashes. My code:

ChildEventListener activeUserschildEventListener = new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {

                for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {

                    UserActive uA = userSnapshot.getValue(UserActive.class);

                    Toast.makeText(MapsActivity.this, uA.getUsername(), Toast.LENGTH_LONG).show();

                }

            }

My error message:

FATAL EXCEPTION: main
Process: shomrim.warpcodes.com.shomrim, PID: 28835
    com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type shomrim.warpcodes.com.shomrim.UserActive
    at com.google.android.gms.internal.zzaln.zzd(Unknown Source)
    at com.google.android.gms.internal.zzaln.zzb(Unknown Source)
    at com.google.android.gms.internal.zzaln.zza(Unknown Source)
    at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
    at shomrim.warpcodes.com.shomrim.MapsActivity$2.onChildAdded(MapsActivity.java:195)
    at com.google.android.gms.internal.zzahe.zza(Unknown Source)
    at com.google.android.gms.internal.zzaje.zzcta(Unknown Source)
    at com.google.android.gms.internal.zzajh$1.run(Unknown Source)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:148)
    at android.app.ActivityThread.main(ActivityThread.java:5417)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

My Firebase structure is like this:

enter image description here

Obviously, there is something that I'm missing with the UserActive class. Please help me if you can. Thanks.

My UserActive class:

package shomrim.warpcodes.com.shomrim;

import android.location.Location;

/**
 * Created by Gil on 09/18/16.
 */

public class UserActive {

    String username;
    Location userlocation;
    String usericoninmap;
    String userphonenumber;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Location getUserlocation() {
        return userlocation;
    }

    public void setUserlocation(Location userlocation) {
        this.userlocation = userlocation;
    }

    public String getUsericoninmap() {
        return usericoninmap;
    }

    public void setUsericoninmap(String usericoninmap) {
        this.usericoninmap = usericoninmap;
    }

    public String getUserphonenumber() {
        return userphonenumber;
    }

    public void setUserphonenumber(String userphonenumber) {
        this.userphonenumber = userphonenumber;
    }
}

My databaseref:

groupPosShareRef = mRootRef.child("groups")
        .child(currentUserGroupsString)
        .child("groupPosData");

The JSON exported from Firebase (after deleting the userlocation part:

"groups" : {
    "-KRietwzwz_5c2oGI0Z8" : {
      "groupPosData" : {
        "DDJxiDshfwbJFLxHXnMg7V5fHqy1" : {
          "username" : "username"
        }
      }

I tried to change the UserActive POJO to one that won't contain the Location object, rather a simple String for lat and lon. It's called UsersActive:

package shomrim.warpcodes.com.shomrim;

/**
 * Created by user on 10/02/16.
 */

public class UsersActive {

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUserlat() {
        return userlat;
    }

    public void setUserlat(String userlat) {
        this.userlat = userlat;
    }

    public String getUserlon() {
        return userlon;
    }

    public void setUserlon(String userlon) {
        this.userlon = userlon;
    }

    public String getUsericoninmap() {
        return usericoninmap;
    }

    public void setUsericoninmap(String usericoninmap) {
        this.usericoninmap = usericoninmap;
    }

    public String getUserphonenumber() {
        return userphonenumber;
    }

    public void setUserphonenumber(String userphonenumber) {
        this.userphonenumber = userphonenumber;
    }

    String username;
    String userlat;
    String userlon;
    String usericoninmap;
    String userphonenumber;

}

Still the app crashes in the same line and with the same error:

            UsersActive uA = userSnapshot.getValue(UsersActive.class);

The new Firebase JSON:

"groups" : {
    "-KRietwzwz_5c2oGI0Z8" : {
      "groupPosData" : {
        "DDDDDDD" : {
          "username" : "username1"
        },
        "DDJxiDshfwbJFLxHXnMg7V5fHqy1" : {
          "username" : "username2"
        }
      }
adjuremods
  • 2,938
  • 2
  • 12
  • 17
Gil A
  • 201
  • 1
  • 13
  • Please post your UserActive java code – Nishant Dubey Oct 02 '16 at 09:26
  • thank you Nishant. for now because it isn't working I didn't fill in the "String usericoninmap, String userphonenumber" strings. but I don't think that that is the problem. – Gil A Oct 02 '16 at 09:33
  • Also share your database ref where you are adding this listener. I think there is a mismatch in ref and your pojo – Nishant Dubey Oct 02 '16 at 09:39
  • my theory is that I need to iterate over the userID (in the image, the line with the "DDJx...", but I'm not sure how to do it. – Gil A Oct 02 '16 at 09:42
  • the databaseref: groupPosShareRef = mRootRef.child("groups") .child(currentUserGroupsString) .child("groupPosData"); – Gil A Oct 02 '16 at 09:42
  • You are already doing it in your for loop – Nishant Dubey Oct 02 '16 at 09:46
  • I think I need to get all the childs of "groupPosData", which are userIDs of active users, and then get for each of them, the actual UserActive data. – Gil A Oct 02 '16 at 09:47
  • I think the issue is with userlocation. Honestly I Have never used pojo with firebase like that. I idea is to get a simple ref and actual children under it with usual data types. You know userlocation is of type Userlocation but firebase doesn't. So it's messing up a little there – Nishant Dubey Oct 02 '16 at 09:51
  • Please just for the sake of testing can you only get userlocaton data with new data ref as userSnapshot.getValue(Location.class) – Nishant Dubey Oct 02 '16 at 09:54
  • give me a minute to understand what you wrote and I'll do it :) – Gil A Oct 02 '16 at 09:57
  • ok what I did was to delete the whole "userlocation" part from firebase, which leaves only the username. but it also crashes in the same error. – Gil A Oct 02 '16 at 10:01
  • when Android Studio yells at me that "com.google.firebase.database.DatabaseException: Can't convert object of type java.lang.String to type shomrim.warpcodes.com.shomrim.UserActive", doesn't it mean that maybe he gets only the userID and thinks that it's a String ? – Gil A Oct 02 '16 at 10:05
  • the line: String uA = (String) dataSnapshot.getValue(); crashes, with the error "java.lang.ClassCastException: java.util.HashMap cannot be cast to java.lang.String". but I get the username in the toast when I try "String uA = userSnapshot.getValue(String.class);" – Gil A Oct 02 '16 at 10:12
  • switched to a version of ActiveUsers POJO that doesn't contain Location, only lat\lon strings, but still the app crashes in the same way in the line " UserActive uA = userSnapshot.getValue(UserActive.class); " – Gil A Oct 02 '16 at 10:39
  • Please can you update the question ? I will do final check and try to post an answer. – Nishant Dubey Oct 02 '16 at 10:41
  • Update new POJO and New firebase database json – Nishant Dubey Oct 02 '16 at 10:41
  • updated it. thank you so much. hope you'll be able to see what I missed.. – Gil A Oct 02 '16 at 10:47

1 Answers1

4

Solved it.

the problem was that I used the ChildEventListener, while I should have used the simple ValueEventListener.

understood it when I realized that the data I get is one step "too deep" than what I needed.

thank Nishant for all the help!

Gil A
  • 201
  • 1
  • 13
  • Am glad you realised there was a data base structural flaw responsible for this. Read more about structuring data here - http://stackoverflow.com/questions/39807789/firebase-fan-out-the-most-cost-effective-way/39810725#39810725 – Nishant Dubey Oct 02 '16 at 15:53