-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update authentication with Google flows (#84)
* Remove sign up with Google button from sign up screen * Launch credential manager bottom sheet as soon as authentication screen starts and create different flows for sign in and sign up * Add flow to show snackbar and add error if no accounts exist for either sign in and sign up * Split sign in and sign up flows, as they call different methods and have different flows from the Firebase Auth perspective * Launch snackbar with no accounts erros when NoCredentialException is thrown * Create AuthenticationViewModel, make SignInViewModel and SignUpViewModel extend and use credential manager flow methods * Add different flow for click on sign in with google button * Resolve comments on PR * Add comment to CredentialsExt and move LaunchEffect up on the authentication screens
- Loading branch information
1 parent
8e0e8bc
commit 1a91c88
Showing
14 changed files
with
224 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
...id/auth-sign-in-with-google/Notes/app/src/main/java/com/notes/app/NotesSnackbarManager.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.notes.app | ||
|
||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.StateFlow | ||
|
||
object SnackbarManager { | ||
private val messages: MutableStateFlow<String?> = MutableStateFlow(null) | ||
val snackbarMessages: StateFlow<String?> | ||
get() = messages | ||
|
||
fun showMessage(message: String) { | ||
messages.value = message | ||
} | ||
|
||
fun clearSnackbarState() { | ||
messages.value = null | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
118 changes: 118 additions & 0 deletions
118
...ith-google/Notes/app/src/main/java/com/notes/app/screens/authentication/CredentialsExt.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package com.notes.app.screens.authentication | ||
|
||
import android.content.Context | ||
import android.util.Log | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.material3.Button | ||
import androidx.compose.material3.ButtonDefaults | ||
import androidx.compose.material3.Icon | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.rememberCoroutineScope | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.platform.LocalContext | ||
import androidx.compose.ui.res.painterResource | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.unit.dp | ||
import androidx.compose.ui.unit.sp | ||
import androidx.credentials.Credential | ||
import androidx.credentials.CredentialManager | ||
import androidx.credentials.GetCredentialRequest | ||
import androidx.credentials.exceptions.GetCredentialException | ||
import androidx.credentials.exceptions.NoCredentialException | ||
import com.google.android.libraries.identity.googleid.GetGoogleIdOption | ||
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption | ||
import com.notes.app.ERROR_TAG | ||
import com.notes.app.R | ||
import com.notes.app.SnackbarManager | ||
import com.notes.app.ui.theme.Purple40 | ||
import kotlinx.coroutines.launch | ||
|
||
@Composable | ||
fun AuthenticationButton(buttonText: Int, onRequestResult: (Credential) -> Unit) { | ||
val context = LocalContext.current | ||
val coroutineScope = rememberCoroutineScope() | ||
|
||
Button( | ||
onClick = { coroutineScope.launch { launchCredManButtonUI(context, onRequestResult) } }, | ||
colors = ButtonDefaults.buttonColors(containerColor = Purple40), | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.padding(16.dp, 0.dp) | ||
) { | ||
Icon( | ||
painter = painterResource(id = R.drawable.google_g), | ||
modifier = Modifier.padding(horizontal = 16.dp), | ||
contentDescription = "Google logo" | ||
) | ||
|
||
Text( | ||
text = stringResource(buttonText), | ||
fontSize = 16.sp, | ||
modifier = Modifier.padding(0.dp, 6.dp) | ||
) | ||
} | ||
} | ||
|
||
private suspend fun launchCredManButtonUI( | ||
context: Context, | ||
onRequestResult: (Credential) -> Unit | ||
) { | ||
try { | ||
val signInWithGoogleOption = GetSignInWithGoogleOption | ||
.Builder(serverClientId = context.getString(R.string.default_web_client_id)) | ||
.build() | ||
|
||
val request = GetCredentialRequest.Builder() | ||
.addCredentialOption(signInWithGoogleOption) | ||
.build() | ||
|
||
val result = CredentialManager.create(context).getCredential( | ||
request = request, | ||
context = context | ||
) | ||
|
||
onRequestResult(result.credential) | ||
} catch (e: NoCredentialException) { | ||
Log.d(ERROR_TAG, e.message.orEmpty()) | ||
SnackbarManager.showMessage(context.getString(R.string.no_accounts_error)) | ||
} catch (e: GetCredentialException) { | ||
Log.d(ERROR_TAG, e.message.orEmpty()) | ||
} | ||
} | ||
|
||
suspend fun launchCredManBottomSheet( | ||
context: Context, | ||
hasFilter: Boolean = true, | ||
onRequestResult: (Credential) -> Unit | ||
) { | ||
try { | ||
val googleIdOption = GetGoogleIdOption.Builder() | ||
.setFilterByAuthorizedAccounts(hasFilter) | ||
.setServerClientId(context.getString(R.string.default_web_client_id)) | ||
.build() | ||
|
||
val request = GetCredentialRequest.Builder() | ||
.addCredentialOption(googleIdOption) | ||
.build() | ||
|
||
val result = CredentialManager.create(context).getCredential( | ||
request = request, | ||
context = context | ||
) | ||
|
||
onRequestResult(result.credential) | ||
} catch (e: NoCredentialException) { | ||
Log.d(ERROR_TAG, e.message.orEmpty()) | ||
|
||
//If the bottom sheet was launched with filter by authorized accounts, we launch it again | ||
//without filter so the user can see all available accounts, not only the ones that have | ||
//been previously authorized in this app | ||
if (hasFilter) { | ||
launchCredManBottomSheet(context, hasFilter = false, onRequestResult) | ||
} | ||
} catch (e: GetCredentialException) { | ||
Log.d(ERROR_TAG, e.message.orEmpty()) | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
...tes/app/screens/sign_up/CredentialsExt.kt → .../screens/authentication/ValidationsExt.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.