GitLiveApp / firebase-kotlin-sdk

A Kotlin-first SDK for Firebase
https://gitliveapp.github.io/firebase-kotlin-sdk/
Apache License 2.0
1.17k stars 156 forks source link

Compose Multiplatform support for Web (Wasm) #440

Open nowiwr01w opened 11 months ago

nowiwr01w commented 11 months ago

@nbransby Hello, can you share your thoughts about wasm support? As I can see, it's relevant for some people (including me) https://github.com/GitLiveApp/firebase-kotlin-sdk/issues/426

nbransby commented 11 months ago

Unless Google adds official support for WASM to Firebase the only way to get it working would be to bind the calls from wasm to the Firebase JS SDK like we do now for traditional JS targets. Im afraid I don't know enough about wasm to comment on how to do this but I can see something similar has been attempted for rust: https://github.com/jquesada2016/firebase-wasm-rs

Thaerith commented 7 months ago

Have you tried to copy/paste the kotlin/js implementation to the wasm ? it is a very naive way to do but packages and the way it works are the same...

maybe could you create a branch where you copy/paste and I can fix the issues ?

DanielWeidensdoerfer commented 6 months ago

Also interested in WASM integration. Currently using js version of firebase in wasm target. Copying the kotlin js implementation to wasm js should work. Some features of kotlin js are not available/different in wasm, so some tweaks could be necessary.

Shanezor12 commented 6 months ago

Also interested in seeing this happen

nowiwr01w commented 6 months ago

Any updates?(

Thaerith commented 6 months ago

I have copy/pasted js variant to wasmJs one but I cannot push my branch... 🙄

nbransby commented 6 months ago

you need to create a fork and push to that and create your pr from there

Thaerith commented 6 months ago

if some of you can build and deploy locally to try -- some classes are missing, trying to replace them

https://github.com/GitLiveApp/firebase-kotlin-sdk/pull/511

Ic-ks commented 6 months ago

@Thaerith I had a short look onto your PR and I am surprised that the compiler for the wasmJS target does not enforce you to use the JsAny types (like JsString, JsBoolean and so on). These types should be used for everything which is passed to, or returned from the JavaScript code. That's one of the main differences between the pure js target and the wasm target: https://kotlinlang.org/docs/wasm-js-interop.html#kotlin-wasm-and-kotlin-js-interoperability-differences I think the copy paste approach is not the best way regarding the maintenance. Maybe it is smarter to create a browser-common configuration with its own sourceset which can be used by the wasmJs target and by the js target. I saw this approach in the popular multiplatform-settings project: https://github.com/russhwolf/multiplatform-settings/ Here the relevant commit: https://github.com/russhwolf/multiplatform-settings/commit/d1c7d9ef69bd20594eefb722c2f6080df86ac4cb

Thaerith commented 6 months ago

You're right, the copy/paste approach cannot work. I pushed to fast, sorry.

I am trying to convert to wasm api (using JsArray...). For most of methods it can work but there is tricky parts (usualy with '.toJSon' extensions) where I'm not sure what to use (using external interfaces seems OK but the extension has to be converted to simple method).

I will check your solution 👌

Ic-ks commented 6 months ago

I followed your copy paste suggestion by myself. But only for the app, auth and common module: https://github.com/Ic-ks/firebase-kotlin-sdk/commit/3933cea9e8ac16efeba0c6ea3fb0dc415eeba722 At the end I was able to get an anonymous firebase user with a test wasmJs app. But there is a lot more to do if the code should be shared between both targets. I can try to support you :)
For the external interfaceit is possible to extend it from JsAny. For FirebaseOptions you can create and use an instance of this class (I found this code in the kotlin slack channel):

@kotlin.js.JsName("Object")
external class JsObject : JsAny {
    operator fun get(key: JsString): JsAny?
    operator fun set(key: JsString, value: JsAny?)
}

fun json(vararg params: Pair<String, Any?>): JsObject {
    return JsObject().apply {
        params.forEach {
            val key = it.first.toJsString()
            when (val value = it.second) {
                is String -> set(key, value.toJsString())
                is Boolean -> set(key, value.toJsBoolean())
                is Int -> set(key, value.toJsNumber())
                is JsObject -> set(key, value)
                is JsString -> set(key, value)
                is JsBoolean -> set(key, value)
                is JsNumber -> set(key, value)
                is JsArray<*> -> set(key, value)
                else -> error("Unsupported type ${it::class}")
            }
        }
    }
}
Hamamas commented 5 months ago

Hi any update

nowiwr01w commented 5 months ago

@Ic-ks @Thaerith Can you guys share a branch if you have something? We can try together

Ic-ks commented 5 months ago

@nowiwr01w I tried to implement a solution which shares code between the js and wasmJs target. My approach was an abstraction layer in the common module which was implemented as jsCommon sourceSet which acts as dependency for the jsMain and wasmJsMain. Unfortunately, I was not able to accomplish this approach, after several hours of tinkering. Right now, I think the easiest way is to enable wasmJs and then copy and paste the jsMain source files to the wasmJsMain folder. Then you have to fix all the compilation error in the wasmJs source files. Most of them are replacements of the special wasmJs types (JsAny, JsString and so on: https://kotlinlang.org/docs/wasm-js-interop.html#kotlin-wasm-and-kotlin-js-interoperability-differences). I did this approach for the common, app and auth module: https://github.com/Ic-ks/firebase-kotlin-sdk/commit/3933cea9e8ac16efeba0c6ea3fb0dc415eeba722

Thaerith commented 4 months ago

Hi I'm currently trying another strategy, which is to use ktor to call firebase rest api directly. so I'm removing step by step gitlive depency

apolostudio commented 4 months ago

Hi I'm currently trying another strategy, which is to use ktor to call firebase rest api directly. so I'm removing step by step gitlive depency

dont you need to have some kind of oauth to connect to those apis?

Thaerith commented 4 months ago

dont you need to have some kind of oauth to connect to those apis?

you can find the documentation with examples here: https://firebase.google.com/docs/reference/rest/auth all you need is your firebase project API KEY replace the base url by localhost:PORT to connect to your emulator

vidicunt commented 2 months ago

Also interested in WASM integration. Currently using js version of firebase in wasm target. Copying the kotlin js implementation to wasm js should work. Some features of kotlin js are not available/different in wasm, so some tweaks could be necessary.

hey, how can i get this working for a compose multiplatform project?

valeriyo commented 1 month ago

@Thaerith have you moved away from gitlive in favor of REST API?

Thaerith commented 1 month ago

Hi, yes I use the rest api for authentication

PMARZV commented 1 month ago

Hi, yes I use the rest api for authentication

Could you provide an example on how to use it?

vidicunt commented 1 month ago

Hi, yes I use the rest api for authentication

Could you provide an example on how to use it?

https://firebase.google.com/docs/reference/rest/auth use ktor to call firebase APIs

PMARZV commented 1 month ago

oh, you only need an api key, i thought i needed to implement the google credentials thing (at least in remote config, it was necessary)