Skip to content

Encoder is no longer accessible? #604

Closed
@mr-kew

Description

@mr-kew
Contributor

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) }
    ...

Activity

Daeda88

Daeda88 commented on Aug 29, 2024

@Daeda88
Contributor

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

mr-kew commented on Aug 29, 2024

@mr-kew
ContributorAuthor

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

Daeda88 commented on Aug 30, 2024

@Daeda88
Contributor

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

mr-kew commented on Aug 30, 2024

@mr-kew
ContributorAuthor

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

Daeda88 commented on Sep 3, 2024

@Daeda88
Contributor

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

mr-kew

mr-kew commented on Sep 3, 2024

@mr-kew
ContributorAuthor

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @Daeda88@mr-kew

      Issue actions

        Encoder is no longer accessible? · Issue #604 · GitLiveApp/firebase-kotlin-sdk