Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encoder is no longer accessible? #604

Closed
mr-kew opened this issue Aug 29, 2024 · 6 comments · May be fixed by #607
Closed

Encoder is no longer accessible? #604

mr-kew opened this issue Aug 29, 2024 · 6 comments · May be fixed by #607

Comments

@mr-kew
Copy link
Contributor

mr-kew commented Aug 29, 2024

I was using the firebase encoder to encode a single values to be used in where statements. It was not flawless because the encoder ignored my @Serializable(with = ...) for some reason, but it worked really well.

But now the encode & firebaseSerializer methods have been made internal, so I can't use them anymore. And I struggle to find any alternatives. Why is this functionality internal all of the sudden? Does this mean I am just screwed now?

My use case:

import dev.gitlive.firebase.FirebaseEncoder
import dev.gitlive.firebase.encode
import dev.gitlive.firebase.firebaseSerializer
... // These imports no longer work, even the @file:Suppress("INVISIBLE_MEMBER", "INVISIBlE_REFERENCE") hack does not help

internal object PrimitiveFirebaseEncoder {
    inline fun <reified T> encodeToAny(value: T): Any? = value?.let {
        encode(it.firebasePrimitiveSerializer(), it) {
            encodeDefaults = true
        }
    }

    /**
     * Allows to override/specify default serializer for a standalone primitive value serialization using [FirebaseEncoder].
     */
    @Suppress("UNCHECKED_CAST")
    private inline fun <reified T : Any> T.firebasePrimitiveSerializer() = when (this) {
        is Instant -> InstantTimestampSerializer
        is LocalDate -> LocalDateTimestampSerializer
        is LocalTime -> LocalTimeIntSerializer
        is LocalDateTime -> LocalDateTimeTimestampSerializer
        is Duration -> DurationSecondsSerializer
        is DayOfWeek -> DayOfWeekIntSerializer
        else -> this.firebaseSerializer()
    } as KSerializer<T>
}

Usage:

val time: Instant = ...
query
    .where { "time" greaterThan PrimitiveFirebaseEncoder.encodeToAny(time) }
    ...
@Daeda88
Copy link
Contributor

Daeda88 commented Aug 29, 2024

It was indeed removed from the public facing api. I guess we never considered adding encoding support for where clauses.

My proposal would be to add support for it to the framework.

Of course, that doesnt solve oyur issue yet. There's two things you can do right now to proceed.

  1. Just serialize yourself. By that I mean instead of doing
query
    .where { "time" greaterThan PrimitiveFirebaseEncoder.encodeToAny(time) }

do

query
    .where { "time" greaterThan time.asPrimitive }

where asPrimitive is used by both the serializer and the where clause.

  1. While it is not encouraged, the firebase-common-internal module should be published and does give access to Encode.

@mr-kew
Copy link
Contributor Author

mr-kew commented Aug 29, 2024

Hmm, I really wanted to use the firebaseSerializer() if I would not specify my custom serializer. But as I look at it now, I can't think of any case where the firestoreSerializer()` would actually do something else than pass the value straight through as is. Is that correct?

Also do I understand correctly, that the second approach does mean doing implementation("...firebase-common-internal")?

And btw, do you have any plans to support this use case in a more complete manner?

@Daeda88
Copy link
Contributor

Daeda88 commented Aug 30, 2024

I'm actually working on a feature to pass the serializer to the where clause. That should resolve it in a cleaner way. Just needs to write some tests and ids good to go.

EDIT: And yes, the second solution means implementing that indeed. Again, I do not recommend it as that module is not intended for public use and may change at any time, but since this fix wont be there in a day, it does unblock you for now.

@mr-kew
Copy link
Contributor Author

mr-kew commented Aug 30, 2024

I'm actually working on a feature to pass the serializer to the where clause.

Cool, that would be super nice.

Again, I do not recommend it as that module is not intended for public use and may change at any time

Yeah, I will probably go for the first approach for those reasons, I was just curious about other options.

@Daeda88
Copy link
Contributor

Daeda88 commented Sep 3, 2024

@mr-kew see #607 Still awaiting approval from the Gitlive team but it should offer all encoding solutions you need

@mr-kew
Copy link
Contributor Author

mr-kew commented Sep 3, 2024

Yes, it looks super promising. It is also much cleaner than my solution with the public encoder. Thank you, Im looking forward to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants