> ## Documentation Index
> Fetch the complete documentation index at: https://www.dynamic.xyz/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Social Authentication

Sign in with Google, Apple, Farcaster, Discord, Twitter, Facebook, or GitHub.

## Setup

1. Enable providers in [Dynamic Dashboard](https://app.dynamic.xyz/dashboard) → **Social**
2. Whitelist your deep link URL in **Security** → **Whitelist Mobile Deeplink**
3. Add OAuth callback activity to `AndroidManifest.xml`:

```xml AndroidManifest.xml theme={"system"}
<!-- OAuth Callback Activity (Required) -->
<activity
    android:name="com.dynamic.sdk.android.Auth.AuthCallbackActivity"
    android:exported="true"
    android:launchMode="singleTop"
    android:noHistory="true"
    android:theme="@android:style/Theme.Translucent.NoTitleBar">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="yourappscheme" />
    </intent-filter>
</activity>
```

## Implementation

### Social Login with Providers

Use the `sdk.auth.social.connect()` method to authenticate with social providers:

```kotlin theme={"system"}
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.Module.Auth.SocialAuthModule

val sdk = DynamicSDK.getInstance()

// Google Sign-In
fun signInWithGoogle() {
    sdk.auth.social.connect(SocialAuthModule.SocialProvider.GOOGLE)
}

// Apple Sign-In
fun signInWithApple() {
    sdk.auth.social.connect(SocialAuthModule.SocialProvider.APPLE)
}

// Farcaster Sign-In
fun signInWithFarcaster() {
    sdk.auth.social.connect(SocialAuthModule.SocialProvider.FARCASTER)
}

// Discord Sign-In
fun signInWithDiscord() {
    sdk.auth.social.connect(SocialAuthModule.SocialProvider.DISCORD)
}

// Twitter Sign-In
fun signInWithTwitter() {
    sdk.auth.social.connect(SocialAuthModule.SocialProvider.TWITTER)
}

// Facebook Sign-In
fun signInWithFacebook() {
    sdk.auth.social.connect(SocialAuthModule.SocialProvider.FACEBOOK)
}

// GitHub Sign-In
fun signInWithGitHub() {
    sdk.auth.social.connect(SocialAuthModule.SocialProvider.GITHUB)
}
```

### Supported Providers

The SDK supports the following social providers:

| Provider  | Enum Value                                  |
| --------- | ------------------------------------------- |
| Google    | `SocialAuthModule.SocialProvider.GOOGLE`    |
| Apple     | `SocialAuthModule.SocialProvider.APPLE`     |
| Farcaster | `SocialAuthModule.SocialProvider.FARCASTER` |
| Discord   | `SocialAuthModule.SocialProvider.DISCORD`   |
| Twitter   | `SocialAuthModule.SocialProvider.TWITTER`   |
| Facebook  | `SocialAuthModule.SocialProvider.FACEBOOK`  |
| GitHub    | `SocialAuthModule.SocialProvider.GITHUB`    |

### Complete Social Authentication Example

Here's a complete example showing how to implement social authentication in Jetpack Compose:

```kotlin theme={"system"}
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Email
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.Module.Auth.SocialAuthModule
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class SocialLoginViewModel : ViewModel() {
    private val sdk = DynamicSDK.getInstance()

    private val _errorMessage = MutableStateFlow<String?>(null)
    val errorMessage: StateFlow<String?> = _errorMessage

    private val _isLoading = MutableStateFlow(false)
    val isLoading: StateFlow<Boolean> = _isLoading

    fun signInWithGoogle() {
        _errorMessage.value = null
        _isLoading.value = true
        try {
            sdk.auth.social.connect(SocialAuthModule.SocialProvider.GOOGLE)
        } catch (e: Exception) {
            _errorMessage.value = "Google sign-in failed: ${e.message}"
            _isLoading.value = false
        }
    }

    fun signInWithApple() {
        _errorMessage.value = null
        _isLoading.value = true
        try {
            sdk.auth.social.connect(SocialAuthModule.SocialProvider.APPLE)
        } catch (e: Exception) {
            _errorMessage.value = "Apple sign-in failed: ${e.message}"
            _isLoading.value = false
        }
    }

    fun signInWithFarcaster() {
        _errorMessage.value = null
        _isLoading.value = true
        try {
            sdk.auth.social.connect(SocialAuthModule.SocialProvider.FARCASTER)
        } catch (e: Exception) {
            _errorMessage.value = "Farcaster sign-in failed: ${e.message}"
            _isLoading.value = false
        }
    }

    fun signInWithDiscord() {
        _errorMessage.value = null
        _isLoading.value = true
        try {
            sdk.auth.social.connect(SocialAuthModule.SocialProvider.DISCORD)
        } catch (e: Exception) {
            _errorMessage.value = "Discord sign-in failed: ${e.message}"
            _isLoading.value = false
        }
    }
}

@Composable
fun SocialLoginScreen(viewModel: SocialLoginViewModel) {
    val errorMessage by viewModel.errorMessage.collectAsState()
    val isLoading by viewModel.isLoading.collectAsState()

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(16.dp),
        verticalArrangement = Arrangement.Center
    ) {
        Text(
            text = "Sign In",
            style = MaterialTheme.typography.headlineLarge,
            modifier = Modifier.padding(bottom = 32.dp)
        )

        // Google button
        Button(
            onClick = { viewModel.signInWithGoogle() },
            modifier = Modifier.fillMaxWidth(),
            enabled = !isLoading,
            colors = ButtonDefaults.buttonColors(
                containerColor = MaterialTheme.colorScheme.surface,
                contentColor = MaterialTheme.colorScheme.onSurface
            )
        ) {
            Text("Continue with Google")
        }

        Spacer(modifier = Modifier.height(12.dp))

        // Apple button
        Button(
            onClick = { viewModel.signInWithApple() },
            modifier = Modifier.fillMaxWidth(),
            enabled = !isLoading,
            colors = ButtonDefaults.buttonColors(
                containerColor = MaterialTheme.colorScheme.surface,
                contentColor = MaterialTheme.colorScheme.onSurface
            )
        ) {
            Text("Continue with Apple")
        }

        Spacer(modifier = Modifier.height(12.dp))

        // Farcaster button
        Button(
            onClick = { viewModel.signInWithFarcaster() },
            modifier = Modifier.fillMaxWidth(),
            enabled = !isLoading,
            colors = ButtonDefaults.buttonColors(
                containerColor = MaterialTheme.colorScheme.surface,
                contentColor = MaterialTheme.colorScheme.onSurface
            )
        ) {
            Text("Continue with Farcaster")
        }

        Spacer(modifier = Modifier.height(12.dp))

        // Discord button
        Button(
            onClick = { viewModel.signInWithDiscord() },
            modifier = Modifier.fillMaxWidth(),
            enabled = !isLoading,
            colors = ButtonDefaults.buttonColors(
                containerColor = MaterialTheme.colorScheme.surface,
                contentColor = MaterialTheme.colorScheme.onSurface
            )
        ) {
            Text("Continue with Discord")
        }

        // Error message
        errorMessage?.let { error ->
            Spacer(modifier = Modifier.height(16.dp))
            Text(
                text = error,
                color = MaterialTheme.colorScheme.error,
                style = MaterialTheme.typography.bodySmall
            )
        }

        // Loading indicator
        if (isLoading) {
            Spacer(modifier = Modifier.height(16.dp))
            CircularProgressIndicator(modifier = Modifier.size(24.dp))
        }
    }
}
```

### Listening for Authentication State

After social authentication succeeds, use Kotlin Flow to handle the authenticated user:

```kotlin theme={"system"}
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.dynamic.sdk.android.DynamicSDK
import com.dynamic.sdk.android.Models.UserProfile
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class AuthManager : ViewModel() {
    private val sdk = DynamicSDK.getInstance()

    private val _user = MutableStateFlow<UserProfile?>(null)
    val user: StateFlow<UserProfile?> = _user

    fun startListening(onAuthenticated: () -> Unit) {
        // Check if already authenticated
        if (sdk.auth.isAuthenticated()) {
            onAuthenticated()
            return
        }

        // Listen for authentication changes
        viewModelScope.launch {
            sdk.auth.authenticatedUserChanges.collect { user ->
                _user.value = user
                if (user != null) {
                    onAuthenticated()
                }
            }
        }
    }
}
```

## Best Practices

### 1. Deep Link URL Management

* Use a consistent deep link URL format
* Ensure the URL is whitelisted in your Dynamic dashboard
* Test deep link handling in your app
* Make sure the `redirectUrl` in `ClientProps` matches your URL scheme

### 2. User Experience

* Show loading states during authentication
* Provide clear error messages
* Handle user cancellation gracefully
* Display provider-specific branding appropriately

### 3. Security

* Never store sensitive authentication data
* Use secure network connections
* Implement proper session management
* Follow provider-specific security guidelines

## Troubleshooting

### Callback Not Working

* Verify your app's URL scheme is configured correctly in `AndroidManifest.xml`
* Check that the `redirectUrl` in `ClientProps` matches your URL scheme
* Ensure your deep link URL is whitelisted in Dynamic dashboard under **Security → Whitelist Mobile Deeplink**
* Verify the `AuthCallbackActivity` is properly configured in your manifest

### Provider Not Working

* Confirm provider is enabled in Dynamic dashboard
* Check that OAuth settings are properly configured
* Verify you have the correct permissions/scopes configured
* Test with a different account to rule out account-specific issues

### Authentication Fails

* Check network connectivity
* Verify provider credentials in Dynamic dashboard
* Ensure the user's account with the provider is valid
* Check for any error messages in Logcat
* Verify the provider app is installed (for Apple, Google, etc.)

## Advanced: Custom Social Button UI

Create custom-styled social login buttons:

```kotlin theme={"system"}
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp

@Composable
fun SocialButton(
    text: String,
    onClick: () -> Unit,
    icon: @Composable () -> Unit,
    backgroundColor: Color = MaterialTheme.colorScheme.surface,
    contentColor: Color = MaterialTheme.colorScheme.onSurface,
    enabled: Boolean = true
) {
    Button(
        onClick = onClick,
        modifier = Modifier
            .fillMaxWidth()
            .height(56.dp),
        enabled = enabled,
        colors = ButtonDefaults.buttonColors(
            containerColor = backgroundColor,
            contentColor = contentColor
        ),
        elevation = ButtonDefaults.buttonElevation(
            defaultElevation = 2.dp
        )
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.Start,
            verticalAlignment = Alignment.CenterVertically
        ) {
            icon()
            Spacer(modifier = Modifier.width(12.dp))
            Text(text = text)
        }
    }
}

@Composable
fun SocialLoginButtons(viewModel: SocialLoginViewModel) {
    Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
        // Google
        SocialButton(
            text = "Continue with Google",
            onClick = { viewModel.signInWithGoogle() },
            icon = {
                // Add your Google icon here
                Text("G", style = MaterialTheme.typography.titleMedium)
            }
        )

        // Apple
        SocialButton(
            text = "Continue with Apple",
            onClick = { viewModel.signInWithApple() },
            icon = {
                // Add your Apple icon here
                Text("", style = MaterialTheme.typography.titleMedium)
            },
            backgroundColor = Color.Black,
            contentColor = Color.White
        )

        // Farcaster
        SocialButton(
            text = "Continue with Farcaster",
            onClick = { viewModel.signInWithFarcaster() },
            icon = {
                // Add your Farcaster icon here
                Text("🟣", style = MaterialTheme.typography.titleMedium)
            }
        )
    }
}
```

## What's Next

Now that you have social authentication set up:

1. **[Session Management](/kotlin/session-management)** - Manage authenticated sessions
2. **[Wallet Operations](/kotlin/wallets)** - Work with user wallets
3. **[MFA](/kotlin/mfa)** - Add multi-factor authentication
4. **[Passkeys](/kotlin/passkeys)** - Implement passwordless authentication
