diff --git a/auth/README.md b/auth/README.md
index ecc3208aa..6061eea06 100644
--- a/auth/README.md
+++ b/auth/README.md
@@ -138,6 +138,7 @@ If using Facebook Login, add your Facebook App ID to `strings.xml`:
YOUR_FACEBOOK_APP_ID
fbYOUR_FACEBOOK_APP_ID
+ CHANGE-ME
```
@@ -489,9 +490,6 @@ Configure Facebook Login with optional permissions:
```kotlin
val facebookProvider = AuthProvider.Facebook(
- // Optional: Facebook application ID (reads from strings.xml if not provided)
- applicationId = "YOUR_FACEBOOK_APP_ID",
-
// Optional: Permissions to request (default: ["email", "public_profile"])
scopes = listOf("email", "public_profile", "user_friends"),
diff --git a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AuthProvider.kt b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AuthProvider.kt
index 1b659a8fc..7e552ec0c 100644
--- a/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AuthProvider.kt
+++ b/auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/AuthProvider.kt
@@ -485,7 +485,7 @@ abstract class AuthProvider(open val providerId: String, open val providerName:
/**
* The OAuth 2.0 client ID for your server.
*/
- val serverClientId: String?,
+ var serverClientId: String?,
/**
* A map of custom OAuth parameters.
@@ -505,8 +505,9 @@ abstract class AuthProvider(open val providerId: String, open val providerName:
" default_web_client_id string wasn't populated.",
R.string.default_web_client_id
)
+ serverClientId = context.getString(R.string.default_web_client_id)
} else {
- require(serverClientId.isNotBlank()) {
+ require(serverClientId!!.isNotBlank()) {
"Server client ID cannot be blank."
}
}
@@ -529,7 +530,7 @@ abstract class AuthProvider(open val providerId: String, open val providerName:
val credential: AuthCredential,
val idToken: String,
val displayName: String?,
- val photoUrl: Uri?
+ val photoUrl: Uri?,
)
/**
@@ -567,7 +568,7 @@ abstract class AuthProvider(open val providerId: String, open val providerName:
credentialManager: CredentialManager,
serverClientId: String,
filterByAuthorizedAccounts: Boolean,
- autoSelectEnabled: Boolean
+ autoSelectEnabled: Boolean,
): GoogleSignInResult
suspend fun clearCredentialState(
@@ -600,8 +601,10 @@ abstract class AuthProvider(open val providerId: String, open val providerName:
.build()
val result = credentialManager.getCredential(context, request)
- val googleIdTokenCredential = GoogleIdTokenCredential.createFrom(result.credential.data)
- val credential = GoogleAuthProvider.getCredential(googleIdTokenCredential.idToken, null)
+ val googleIdTokenCredential =
+ GoogleIdTokenCredential.createFrom(result.credential.data)
+ val credential =
+ GoogleAuthProvider.getCredential(googleIdTokenCredential.idToken, null)
return GoogleSignInResult(
credential = credential,
@@ -624,11 +627,6 @@ abstract class AuthProvider(open val providerId: String, open val providerName:
* Facebook Login provider configuration.
*/
class Facebook(
- /**
- * The Facebook application ID.
- */
- val applicationId: String? = null,
-
/**
* The list of scopes (permissions) to request. Defaults to email and public_profile.
*/
@@ -653,18 +651,26 @@ abstract class AuthProvider(open val providerId: String, open val providerName:
)
}
- if (applicationId == null) {
- Preconditions.checkConfigured(
- context,
- "Facebook provider unconfigured. Make sure to " +
- "add a `facebook_application_id` string or provide applicationId parameter.",
- R.string.facebook_application_id
- )
- } else {
- require(applicationId.isNotBlank()) {
- "Facebook application ID cannot be blank"
- }
- }
+ Preconditions.checkConfigured(
+ context,
+ "Facebook provider unconfigured. Make sure to " +
+ "add a `facebook_application_id` string to your strings.xml",
+ R.string.facebook_application_id
+ )
+
+ Preconditions.checkConfigured(
+ context,
+ "Facebook provider unconfigured. Make sure to " +
+ "add a `facebook_login_protocol_scheme` string to your strings.xml",
+ R.string.facebook_login_protocol_scheme
+ )
+
+ Preconditions.checkConfigured(
+ context,
+ "Facebook provider unconfigured. Make sure to " +
+ "add a `facebook_client_token` string to your strings.xml",
+ R.string.facebook_client_token
+ )
}
/**
diff --git a/auth/src/test/java/com/firebase/ui/auth/configuration/AuthUIConfigurationTest.kt b/auth/src/test/java/com/firebase/ui/auth/configuration/AuthUIConfigurationTest.kt
index 80cf85ad6..4afcfa84b 100644
--- a/auth/src/test/java/com/firebase/ui/auth/configuration/AuthUIConfigurationTest.kt
+++ b/auth/src/test/java/com/firebase/ui/auth/configuration/AuthUIConfigurationTest.kt
@@ -294,12 +294,13 @@ class AuthUIConfigurationTest {
}
@Test
+ @Config(manifest = Config.NONE, qualifiers = "night")
fun `validation accepts all supported providers`() {
val config = authUIConfiguration {
context = applicationContext
providers {
provider(AuthProvider.Google(scopes = listOf(), serverClientId = "test_client_id"))
- provider(AuthProvider.Facebook(applicationId = "test_app_id"))
+ provider(AuthProvider.Facebook())
provider(AuthProvider.Twitter(customParameters = mapOf()))
provider(AuthProvider.Github(customParameters = mapOf()))
provider(AuthProvider.Microsoft(customParameters = mapOf(), tenant = null))
diff --git a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AuthProviderTest.kt b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AuthProviderTest.kt
index f64bfc2a6..718d38ad3 100644
--- a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AuthProviderTest.kt
+++ b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/AuthProviderTest.kt
@@ -2,6 +2,7 @@ package com.firebase.ui.auth.configuration.auth_provider
import android.content.Context
import androidx.test.core.app.ApplicationProvider
+import com.firebase.ui.auth.R
import com.google.common.truth.Truth.assertThat
import com.google.firebase.auth.actionCodeSettings
import org.junit.Before
@@ -264,32 +265,34 @@ class AuthProviderTest {
}
}
+ @Test
+ @Config(manifest = Config.NONE, qualifiers = "night")
+ fun `google provider assigns default_web_client_id to serverClientId when null`() {
+ val provider = AuthProvider.Google(
+ scopes = listOf("email"),
+ serverClientId = null
+ )
+
+ provider.validate(applicationContext)
+
+ assertThat(provider.serverClientId)
+ .isEqualTo(applicationContext.getString(R.string.default_web_client_id))
+ }
+
// =============================================================================================
// Facebook Provider Tests
// =============================================================================================
@Test
+ @Config(manifest = Config.NONE, qualifiers = "night")
fun `facebook provider with valid configuration should succeed`() {
- val provider = AuthProvider.Facebook(applicationId = "application_id")
+ val provider = AuthProvider.Facebook()
provider.validate(applicationContext)
}
@Test
- fun `facebook provider with empty application id throws`() {
- val provider = AuthProvider.Facebook(applicationId = "")
-
- try {
- provider.validate(applicationContext)
- assertThat(false).isTrue() // Should not reach here
- } catch (e: Exception) {
- assertThat(e).isInstanceOf(IllegalArgumentException::class.java)
- assertThat(e.message).isEqualTo("Facebook application ID cannot be blank")
- }
- }
-
- @Test
- fun `facebook provider validates facebook_application_id when applicationId is null`() {
+ fun `facebook provider validates facebook_application_id`() {
val provider = AuthProvider.Facebook()
try {
@@ -299,7 +302,7 @@ class AuthProviderTest {
assertThat(e).isInstanceOf(IllegalStateException::class.java)
assertThat(e.message).isEqualTo(
"Facebook provider unconfigured. Make sure to " +
- "add a `facebook_application_id` string or provide applicationId parameter."
+ "add a `facebook_application_id` string to your strings.xml"
)
}
}
@@ -400,4 +403,4 @@ class AuthProviderTest {
assertThat(e.message).isEqualTo("Button label cannot be null or empty")
}
}
-}
\ No newline at end of file
+}
diff --git a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProviderFirebaseAuthUI.kt b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProviderFirebaseAuthUI.kt
index 155de1f82..1e48bae90 100644
--- a/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProviderFirebaseAuthUI.kt
+++ b/auth/src/test/java/com/firebase/ui/auth/configuration/auth_provider/FacebookAuthProviderFirebaseAuthUI.kt
@@ -103,6 +103,7 @@ class FacebookAuthProviderFirebaseAuthUITest {
}
@Test
+ @Config(manifest = Config.NONE, qualifiers = "night")
fun `signInWithFacebook - successful sign in signs user in and emits Success authState`() = runTest {
val authStateListeners = mutableListOf()
doAnswer { invocation ->
@@ -118,9 +119,7 @@ class FacebookAuthProviderFirebaseAuthUITest {
whenever(mockFirebaseAuth.currentUser).thenReturn(null)
val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth)
- val provider = spy(AuthProvider.Facebook(
- applicationId = "000000000000"
- ))
+ val provider = spy(AuthProvider.Facebook())
val config = authUIConfiguration {
context = applicationContext
providers {
@@ -175,6 +174,7 @@ class FacebookAuthProviderFirebaseAuthUITest {
}
@Test
+ @Config(manifest = Config.NONE, qualifiers = "night")
fun `signInWithFacebook - handles account collision by saving credential and emitting error`() = runTest {
EmailLinkPersistenceManager.default.clear(applicationContext)
EmailLinkPersistenceManager.default.saveEmail(
@@ -185,9 +185,7 @@ class FacebookAuthProviderFirebaseAuthUITest {
)
val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth)
- val provider = spy(AuthProvider.Facebook(
- applicationId = "000000000000"
- ))
+ val provider = spy(AuthProvider.Facebook())
val config = authUIConfiguration {
context = applicationContext
providers {
@@ -238,11 +236,10 @@ class FacebookAuthProviderFirebaseAuthUITest {
}
@Test
+ @Config(manifest = Config.NONE, qualifiers = "night")
fun `signInWithFacebook - converts FacebookException into AuthException`() = runTest {
val instance = FirebaseAuthUI.create(firebaseApp, mockFirebaseAuth)
- val provider = spy(AuthProvider.Facebook(
- applicationId = "000000000000"
- ))
+ val provider = spy(AuthProvider.Facebook())
val config = authUIConfiguration {
context = applicationContext
providers {
diff --git a/auth/src/test/res/values-night/config.xml b/auth/src/test/res/values-night/config.xml
new file mode 100644
index 000000000..0b31fe015
--- /dev/null
+++ b/auth/src/test/res/values-night/config.xml
@@ -0,0 +1,7 @@
+
+
+ test_client_id
+ test_app_id
+ test_login_scheme
+ test_client_token
+