mk-5 / gdx-fireapp

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

Transaction writes emptry String with Kotlin Long if value doesn't exist #28

Closed florianbaethge closed 4 years ago

florianbaethge commented 4 years ago

Describe the bug I would like to increase a Long value in the database using a transaction. If the field already exists in the database and contains a float, it works fine, but if it doesn't exist, the transaction will run through without an error, but instead of writing a new number, an empty String is written in the database:

val function = Function<Long, Long> { var1 ->
      (var1 ?: 0L).plus(value)
}

GdxFIRDatabase.inst()
                    .inReference(reference)
                    .transaction(Long::class.java, function)
                    .subscribe {
                        Gdx.app.log(TAG, "Successfully wrote to $reference")
                    }.fail { s, throwable ->
                        Gdx.app.error(TAG, "ERROR PERFORMING TRANSACTION")
                        Gdx.app.error(TAG, s, throwable)
                        listener?.failure(s, throwable)
                    }

Expected behavior If the value doesn't exist yet, it should just use 0 in the function and add the value and write to the databse

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

Hi!

Thanks for reporting. I will look at this really soon, and I will come back to you with some answer.

mk-5 commented 4 years ago

Increasing of Long within transaction should work pretty good - I have e2e test for exactly for that. When there is no value for a given reference path, the API creates a default value for class type. In your case, the problem may occur because Long::class.java in Kotlin is not a java Long representation. It's really tricky :) Take a look here: https://pl.kotl.in/e07iAZPbs

Can you change your code to:

.transaction(java.lang.Long::class.java, function)

and let me know if that would help?

I think some API adjustments will be nice at that area

florianbaethge commented 4 years ago

Thanks for the fast help!

Yes I figured this has something to do with Kotlin and Java differences :(

The thing is, that I can't write a function in Kotlin that uses the java.lang.Long... if I declare the types of that function with the java type, I cannot even use as "+"-operator because Kotlin doesn't know that operation.

If I write an extra Java class that would create the function with java types and return it, the Kotlin class would still interpret the result as a Function<kotlin.Long, kotlin.Long>...

So to avoid this, all I can do is to write the complete transaction function in a Java class instead... which doesn't really satisfy me ;)

Do you have any plans extending the API so it would also understand Kotlin primitive types?

florianbaethge commented 4 years ago

Moving the whole database write process to a Java class did solve that problem for me, but it's quite inconvenient... My original database functions use generic callback listeners, which don't play nicely with Java as well. But still, at least that's a first temporary solution :D

mk-5 commented 4 years ago

Yes, I will add Kotlin types recognizing, it shouldn't be a problem. I've added such a feature to readValue method - there was exactly the same problem like this one :)