Search code examples
javafirebasefirebase-realtime-databaselibgdx

Downloading list from Firebase using 'gdx-fireapp' returns list of objects with empty fields


I'm trying to deal with Firebase in a LibGdx app using gdx-fireapp library.

I followed the given examples from here. I have problems with "dowloading a list" sample:

I created the POJO "user" class and wrote successfully a user in database...so database contains a list of 1 user with all fields filled in (verified in database console).

Now when I try to download the list of users with the exact given code, I get a list with 1 user (OK), which all fieds are NULL

Here is the "user" POJO class

public class UserPOJO{
  public String username;
  public String email;
  public UserPOJO(){}
  public UserPOJO(String username, String email){
    this.username = username;
    this.email = email;
  }
}

And here is the code to retrieve the list of users :

public static void readUsersJava (){
    GdxFIRDatabase.instance().inReference("users")
            .filter(FilterType.LIMIT_FIRST, 5)
            .readValue(List.class, new DataCallback<List<UserPOJO>>(){
                @MapConversion(UserPOJO.class)
                @Override
                public void onData(List<UserPOJO> list) {
                    Gdx.app.log("Firebase Java", "read users OK");
                }
                @Override
                public void onError(Exception e) {
                    Gdx.app.log("Firebase Java", "read users KO");
                }
            });
}

As I know the user's Id, I can try to read if from database with

    GdxFIRDatabase.instance().inReference("users/Xc4x0IOm...")
            .readValue(UserPOJO.class, new DataCallback<UserPOJO>() {...}

but doing this, i get "java.lang.ClassCastException: java.util.HashMap cannot be cast to UserPOJO".
This is probably why fields are empty : can't cast... But I can't find how to get rid of this error

Can somebody help me please ?


Solution

  • OK I found this : the query answer is a Hashmap<String, Hashmap<String, String>>

    so I had to :

    1. add a 'order by' clause -> that consumes the first level hashmap (I don't know why)
      that seems to be mandatory for list queries
    2. create a custom mapping of my 'user' class

    so the code looks like this : (no change on 'user' class)

    public static void readUsersJava (){
    setUsersMapConverter()
    GdxFIRDatabase.instance().inReference("users")
            .orderBy(OrderByMode.ORDER_BY_KEY, null)
            .filter(FilterType.LIMIT_FIRST, 5)
            .readValue(List.class, new DataCallback<List<UserPOJO>>(){
            ...
            });
    }
    

    and

    fun setUsersMapConverter(){
        GdxFIRDatabase.instance().setMapConverter(object : FirebaseMapConverter {
            override fun <T : Any?> convert(map: MutableMap<String, Any>, wantedType: Class<T>): T {
                val element = (map.get(map.keys.first())) as HashMap<String, String>
                return UserPOJO(element.get("displayName"), element.get("email")) as T
            }
            // Should be inversion of convert (needed only by GWT platform)
            override fun unConvert(`object`: Any): Map<String, Any>? {
                return null
            }
        })
    }
    

    Hope that can help.

    Let me know if you find a better solution.