mk-5 / gdx-fireapp

libGDX Firebase API
Apache License 2.0
65 stars 21 forks source link

Filters/orderBy are not resetted between multiple queries #31

Closed florianbaethge closed 4 years ago

florianbaethge commented 4 years ago

Describe the bug I've just tried to perform several database fetch calls, but it seems that the database instance somehow keeps the filters made on another query.

When I change the order of the queries and fetch the one without filters first, it works! But if the fetch without filter or orderBy settings is called after the other one, it crashes with an IllegalStateException:

Caused by: java.lang.IllegalStateException: The filter should be applied only for List or Map type
        at pl.mk5.gdx.fireapp.database.FilteringStateEnsurer.checkFilteringState(FilteringStateEnsurer.java:44)
        at pl.mk5.gdx.fireapp.android.database.Database.onDataChange(Database.java:138)
        at pl.mk5.gdx.fireapp.GdxFIRDatabase.onDataChange(GdxFIRDatabase.java:103) 

To Reproduce

// Database scheme

"highscores": {
    "UID1": {
        "highscore": -123,
        "timestamp": 12345667
    },
    "UID1": {
        "highscore": -123,
        "timestamp": 12345667
    }
    "UID1": {
        "highscore": -123,
        "timestamp": 12345667
    }
}

// get 5 first highscores starting at -100 value
GdxFIRDatabase.inst()
        .inReference(reference)
        .orderBy(OrderByMode.ORDER_BY_CHILD, "highscore")
        .filter(FilterType.LIMIT_FIRST, 5)
        .filter(FilterType.START_AT, -100.0)
        .readValue(List::class.java)
        .then (object : Consumer<List<Highscore>> {

            @MapConversion(Highscore::class)
            override fun accept(data: List<Highscore>?) {
                Gdx.app.log(TAG, "Successfully fetched from $reference")
                Gdx.app.log(TAG, "Highscores: $data")
            }

        })
        .fail { s, throwable ->
            Gdx.app.error(TAG, "ERROR FETCHING HIGHSCORES ")
            Gdx.app.error(TAG, s, throwable)
        }

// get individual highscore for user

val promise = GdxFIRDatabase.inst()
        .inReference("$reference/${user.userInfo.uid}")
        .onDataChange(Highscore::class.java)
        .thenListener { data ->
            Gdx.app.log(TAG, "Successfully fetched from $reference")

            if(data != null) {    
                Gdx.app.log(TAG, "Highscore for ${user.userInfo.uid}: $data")
            } else {
                Gdx.app.log(TAG, "User is not in highscore: $data")
            }
        }
promise.fail { s, throwable ->
    Gdx.app.error(TAG, "ERROR FETCHING")
    Gdx.app.error(TAG, s, throwable)
}

If you change the order of the queries (move the whole val promise = ... part above the rest, it works.

Expected behavior Calls should work in any order. First call should answer with a list of Highscores, second one an individual one, if the uid has a highscore in the database...

Platform (please check one of the following):

Smartphone (please complete the following information only if platform is Android or iOS):

mk-5 commented 4 years ago

Thanks for reporting!

Please, expect some news here. I will take this topic up, as soon as possible ;)

mk-5 commented 4 years ago

Please check the latest version 1.3.6 - that should help.

If I may be honest, I haven't reproduced your issue, but I think I found the reason. "Query state" was cleaned up after firebase execution. In case of concurrent calls (like data change listening + read value once), that probably had caused problems.

mk-5 commented 4 years ago

@florianbaethge have you checked if the latest version works for you :)?

florianbaethge commented 4 years ago

Hi,

sorry for not writing back. I've upgraded the version and tried it. Works for me :) Thank you!