google / play-services-plugins

Plugins to help with using Google Play services SDK.
https://developers.google.com/android/guides/overview
Apache License 2.0
471 stars 138 forks source link

The generated resource String 'default_web_client_id' is only available on the main application module, breaking modularization #294

Open NinoDLC opened 6 months ago

NinoDLC commented 6 months ago

Describe the bug The generated resource String 'default_web_client_id' is only available on the main application module, breaking modularization.

My app module depends on say login feature module. Inside login module, I handle the connection stuff.

Inside the app module, I can use getString(R.string.default_web_client_id). Inside the login module, I can't because it's not generated for my module.

To Reproduce Steps to reproduce the behavior: 1/ Try to implement the firebase-auth inside a library module instead of an application module 2/ Fail

Expected behavior We should be able to modularize our application.

Desktop (please complete the following information):

Additional context This is my setup: build.gradle.kts (root):

plugins {
    ...
    alias(libs.plugins.googleServices) apply false
}

gradle/libs.versions.toml:

[versions]
googleServicesVersion = "4.4.1"

...

[plugins]
googleServices = { id = "com.google.gms.google-services", version.ref = "googleServicesVersion " }

app/build.gradle.kts (module):

plugins {
    ...
    alias(libs.plugins.googleServices)
}

Note: If I apply the plugin in the login/build.gradle.kts to try to generate the resource String in my module, it says The google-services Gradle plugin needs to be applied on a project with com.android.application or com.android.dynamic-feature. so either way I'm doomed 🤷

ZhEgor commented 1 month ago

@NinoDLC I believe you can make a workaround, if you have a common module between your app and login module, you can preserve value from R.string.default_web_client_id in a local variable. After that you can access this variable from the login module.

Definitely not the best approach, but at least it resolves a blocker. If you have faced this issue, and found a better approach, please let me know.

ZhEgor commented 1 month ago

if you use compose, you can achieve the workaround by something like this:

common module:

val LocalDefaultWebClientId = staticCompositionLocalOf<String> {
    error("CompositionLocal LocalDefaultWebClientId not present")
}

app module:

CompositionLocalProvider(LocalDefaultWebClientId provides stringResource(R.string.default_web_client_id)) {
    ...
}

login module:

val defaultWebClientId = LocalDefaultWebClientId.current

Button(
        onClick = {
            val googleIdOption = GetGoogleIdOption.Builder()
                .setFilterByAuthorizedAccounts(false)
                .setServerClientId(defaultWebClientId)
                .build()
            val request = GetCredentialRequest.Builder()
                .addCredentialOption(googleIdOption)
                .build()
            scope.launch {
                try {
                    val result = credentialManager.getCredential(
                        request = request,
                        context = context
                    )
                    onGetCredentialSuccess.invoke(result.credential)
                } catch (e: Exception) {
                    onGetCredentialFailure.invoke(e)
                }
            }
        }
)