From 75664ce2a2a4f76ba6c48a23394bab20d0d1816b Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Thu, 23 Jan 2025 16:33:13 +0100 Subject: [PATCH 01/10] wip --- packages/authentication/android/build.gradle | 9 + .../FirebaseAuthentication.java | 8 - .../FirebaseAuthenticationPlugin.java | 16 -- .../handlers/GoogleAuthProviderHandler.java | 187 ++++++++---------- 4 files changed, 93 insertions(+), 127 deletions(-) diff --git a/packages/authentication/android/build.gradle b/packages/authentication/android/build.gradle index 64d61022..f33ccaa5 100644 --- a/packages/authentication/android/build.gradle +++ b/packages/authentication/android/build.gradle @@ -8,6 +8,9 @@ ext { firebaseAuthVersion = project.hasProperty('firebaseAuthVersion') ? rootProject.ext.firebaseAuthVersion : '22.3.1' playServicesAuthVersion = project.hasProperty('playServicesAuthVersion') ? rootProject.ext.playServicesAuthVersion : '21.0.0' facebookLoginVersion = project.hasProperty('facebookLoginVersion') ? rootProject.ext.facebookLoginVersion : '16.3.0' + androidxCredentialsVersion = project.hasProperty('androidxCredentialsVersion') ? rootProject.ext.androidxCredentialsVersion : '1.5.0-rc01' + androidxCredentialsPlayServicesAuthVersion = project.hasProperty('androidxCredentialsPlayServicesAuthVersion') ? rootProject.ext.androidxCredentialsPlayServicesAuthVersion : '1.5.0-rc01' + librariesIdentityGoogleidVersion = project.hasProperty('librariesIdentityGoogleidVersion') ? rootProject.ext.librariesIdentityGoogleidVersion : '1.1.1' } buildscript { @@ -60,8 +63,14 @@ dependencies { implementation "com.google.firebase:firebase-auth:$firebaseAuthVersion" if (rgcfaIncludeGoogle) { implementation "com.google.android.gms:play-services-auth:$playServicesAuthVersion" + implementation "androidx.credentials:credentials:$androidxCredentialsVersion" + implementation "androidx.credentials:credentials-play-services-auth:$androidxCredentialsPlayServicesAuthVersion" + implementation "com.google.android.libraries.identity.googleid:googleid:$librariesIdentityGoogleidVersion" } else { compileOnly "com.google.android.gms:play-services-auth:$playServicesAuthVersion" + compileOnly "androidx.credentials:credentials:$androidxCredentialsVersion" + compileOnly "androidx.credentials:credentials-play-services-auth:$androidxCredentialsPlayServicesAuthVersion" + compileOnly "com.google.android.libraries.identity.googleid:googleid:$librariesIdentityGoogleidVersion" } if (rgcfaIncludeFacebook) { implementation "com.facebook.android:facebook-login:$facebookLoginVersion" diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java index a6437ae6..e705f7bd 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java @@ -646,14 +646,6 @@ public void startActivityForResult(final PluginCall call, Intent intent, String plugin.startActivityForResult(call, intent, callbackName); } - public void handleGoogleAuthProviderSignInActivityResult(@NonNull final PluginCall call, @NonNull ActivityResult result) { - googleAuthProviderHandler.handleOnActivityResult(call, result, false); - } - - public void handleGoogleAuthProviderLinkActivityResult(@NonNull final PluginCall call, @NonNull ActivityResult result) { - googleAuthProviderHandler.handleOnActivityResult(call, result, true); - } - public void handlePlayGamesAuthProviderSignInActivityResult(@NonNull final PluginCall call, @NonNull ActivityResult result) { playGamesAuthProviderHandler.handleOnActivityResult(call, result, false); } diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java index d13ab6ed..8d0df811 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java @@ -1009,22 +1009,6 @@ protected void handleOnActivityResult(int requestCode, int resultCode, @Nullable implementation.handleOnActivityResult(requestCode, resultCode, data); } - @ActivityCallback - private void handleGoogleAuthProviderSignInActivityResult(@Nullable PluginCall call, @Nullable ActivityResult result) { - if (call == null || result == null) { - return; - } - implementation.handleGoogleAuthProviderSignInActivityResult(call, result); - } - - @ActivityCallback - private void handleGoogleAuthProviderLinkActivityResult(@Nullable PluginCall call, @Nullable ActivityResult result) { - if (call == null || result == null) { - return; - } - implementation.handleGoogleAuthProviderLinkActivityResult(call, result); - } - @ActivityCallback private void handlePlayGamesAuthProviderSignInActivityResult(@Nullable PluginCall call, @Nullable ActivityResult result) { if (call == null || result == null) { diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java index a24da6ce..751c33d3 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java @@ -1,139 +1,120 @@ package io.capawesome.capacitorjs.plugins.firebase.authentication.handlers; -import android.content.Intent; -import android.util.Log; -import androidx.activity.result.ActivityResult; +import androidx.credentials.ClearCredentialStateRequest; +import androidx.credentials.Credential; +import androidx.credentials.CredentialManager; + +import android.os.Bundle; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import com.getcapacitor.JSArray; +import androidx.credentials.CredentialManagerCallback; +import androidx.credentials.CustomCredential; +import androidx.credentials.GetCredentialRequest; +import androidx.credentials.GetCredentialResponse; +import androidx.credentials.exceptions.ClearCredentialException; +import androidx.credentials.exceptions.GetCredentialException; + +import com.getcapacitor.Logger; import com.getcapacitor.PluginCall; -import com.google.android.gms.auth.GoogleAuthException; -import com.google.android.gms.auth.GoogleAuthUtil; -import com.google.android.gms.auth.api.signin.GoogleSignIn; -import com.google.android.gms.auth.api.signin.GoogleSignInAccount; -import com.google.android.gms.auth.api.signin.GoogleSignInClient; -import com.google.android.gms.auth.api.signin.GoogleSignInOptions; -import com.google.android.gms.common.api.ApiException; -import com.google.android.gms.common.api.Scope; -import com.google.android.gms.tasks.Task; +import com.google.android.libraries.identity.googleid.GetGoogleIdOption; +import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential; import com.google.firebase.auth.AuthCredential; import com.google.firebase.auth.GoogleAuthProvider; import io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthentication; -import io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthenticationPlugin; import io.capawesome.capacitorjs.plugins.firebase.authentication.R; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import org.json.JSONException; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; public class GoogleAuthProviderHandler { private FirebaseAuthentication pluginImplementation; - private GoogleSignInClient mGoogleSignInClient; public GoogleAuthProviderHandler(FirebaseAuthentication pluginImplementation) { this.pluginImplementation = pluginImplementation; - this.mGoogleSignInClient = buildGoogleSignInClient(); } - public void signIn(PluginCall call) { - mGoogleSignInClient = buildGoogleSignInClient(call); - Intent signInIntent = mGoogleSignInClient.getSignInIntent(); - pluginImplementation.startActivityForResult(call, signInIntent, "handleGoogleAuthProviderSignInActivityResult"); + public void signIn(final PluginCall call) { + signInOrLink(call, false); } - public void link(PluginCall call) { - mGoogleSignInClient = buildGoogleSignInClient(call); - Intent signInIntent = mGoogleSignInClient.getSignInIntent(); - pluginImplementation.startActivityForResult(call, signInIntent, "handleGoogleAuthProviderLinkActivityResult"); + public void link(final PluginCall call) { + signInOrLink(call, true); } public void signOut() { - mGoogleSignInClient.signOut(); - } - - public void handleOnActivityResult(@NonNull final PluginCall call, @NonNull ActivityResult result, boolean isLink) { - Intent data = result.getData(); - Task task = GoogleSignIn.getSignedInAccountFromIntent(data); - try { - GoogleSignInAccount account = task.getResult(ApiException.class); - String idToken = account.getIdToken(); - String serverAuthCode = account.getServerAuthCode(); - AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null); - // Get Access Token and resolve - new Thread( - () -> { - String accessToken = null; - List scopes = new ArrayList<>(); - scopes.add("oauth2:email"); - scopes.addAll(getScopesAsList(call)); - - try { - accessToken = - GoogleAuthUtil.getToken( - mGoogleSignInClient.getApplicationContext(), - account.getAccount(), - String.join(" ", scopes) - ); - // Clears local cache after every login attempt - // to ensure permissions changes elsewhere are reflected in future tokens - GoogleAuthUtil.clearToken(mGoogleSignInClient.getApplicationContext(), accessToken); - } catch (IOException | GoogleAuthException exception) { - if (isLink) { - pluginImplementation.handleFailedLink(call, null, exception); - } else { - pluginImplementation.handleFailedSignIn(call, null, exception); - } - return; + ClearCredentialStateRequest request = new ClearCredentialStateRequest(); + Executor executor = Executors.newSingleThreadExecutor(); + CredentialManager credentialManager = CredentialManager.create(pluginImplementation.getPlugin().getActivity()); + credentialManager.clearCredentialStateAsync( + request, + null, + executor, + new CredentialManagerCallback() { + @Override + public void onResult(Void result) { + // TODO } - if (isLink) { - pluginImplementation.handleSuccessfulLink(call, credential, idToken, null, accessToken, serverAuthCode); - } else { - pluginImplementation.handleSuccessfulSignIn(call, credential, idToken, null, accessToken, serverAuthCode, null); + + @Override + public void onError(ClearCredentialException exception) { + // TODO + Logger.error("Error signing out", exception); } } - ) - .start(); - } catch (ApiException exception) { - if (isLink) { - pluginImplementation.handleFailedLink(call, null, exception); - } else { - pluginImplementation.handleFailedSignIn(call, null, exception); - } - } + ); } - private GoogleSignInClient buildGoogleSignInClient() { - return buildGoogleSignInClient(null); + private void handleGetCredentialError(final PluginCall call, final boolean isLink, final GetCredentialException exception) { + if (isLink) { + pluginImplementation.handleFailedLink(call, null, exception); + } else { + pluginImplementation.handleFailedSignIn(call, null, exception); + } } - private GoogleSignInClient buildGoogleSignInClient(@Nullable PluginCall call) { - GoogleSignInOptions.Builder googleSignInOptionsBuilder = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) - .requestIdToken(pluginImplementation.getPlugin().getContext().getString(R.string.default_web_client_id)) - .requestServerAuthCode(pluginImplementation.getPlugin().getContext().getString(R.string.default_web_client_id)) - .requestEmail(); - - if (call != null) { - List scopeList = getScopesAsList(call); - for (String scope : scopeList) { - googleSignInOptionsBuilder = googleSignInOptionsBuilder.requestScopes(new Scope(scope)); + private void handleGetCredentialResult(final PluginCall call, final boolean isLink, final GetCredentialResponse response) { + Credential credential = response.getCredential(); + if (credential.getType().equals(GoogleIdTokenCredential.TYPE_GOOGLE_ID_TOKEN_CREDENTIAL)) { + Bundle data = credential.getData(); + GoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(data); + String idToken = googleIdTokenCredential.getIdToken(); + AuthCredential authCredential = GoogleAuthProvider.getCredential(idToken, null); + if (isLink) { + pluginImplementation.handleSuccessfulLink(call, authCredential, idToken, null, null, null); + } else { + pluginImplementation.handleSuccessfulSignIn(call, authCredential, idToken, null, null, null, null); } } - - return GoogleSignIn.getClient(pluginImplementation.getPlugin().getActivity(), googleSignInOptionsBuilder.build()); } - private List getScopesAsList(@NonNull PluginCall call) { - List scopeList = new ArrayList<>(); - JSArray scopes = call.getArray("scopes"); - if (scopes != null) { - try { - scopeList = scopes.toList(); - } catch (JSONException exception) { - Log.e(FirebaseAuthenticationPlugin.TAG, "getScopesAsList failed.", exception); - } - } + public void signInOrLink(final PluginCall call, final boolean isLink) { + Executor executor = Executors.newSingleThreadExecutor(); + GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder() + // Your server's client ID, not your Android client ID + .setServerClientId(pluginImplementation.getPlugin().getContext().getString(R.string.default_web_client_id)) + // Show all accounts on the device (not just the accounts that have been used previously) + .setFilterByAuthorizedAccounts(false) + .build(); + GetCredentialRequest request = new GetCredentialRequest.Builder() + .addCredentialOption(googleIdOption) + .build(); + CredentialManager credentialManager = CredentialManager.create(pluginImplementation.getPlugin().getActivity()); + credentialManager.getCredentialAsync( + pluginImplementation.getPlugin().getContext(), + request, + null, + executor, + new CredentialManagerCallback() { + @Override + public void onResult(GetCredentialResponse response) { + handleGetCredentialResult(call, isLink, response); + } - return scopeList; + @Override + public void onError(@NonNull GetCredentialException exception) { + handleGetCredentialError(call, isLink, exception); + } + } + ); } } From a949062d78065957212b10a34b70526bf8293562 Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Fri, 24 Jan 2025 09:11:57 +0100 Subject: [PATCH 02/10] wip --- .../handlers/GoogleAuthProviderHandler.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java index 751c33d3..c04ecddd 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java @@ -7,7 +7,6 @@ import android.os.Bundle; import androidx.annotation.NonNull; import androidx.credentials.CredentialManagerCallback; -import androidx.credentials.CustomCredential; import androidx.credentials.GetCredentialRequest; import androidx.credentials.GetCredentialResponse; import androidx.credentials.exceptions.ClearCredentialException; @@ -21,6 +20,7 @@ import com.google.firebase.auth.GoogleAuthProvider; import io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthentication; import io.capawesome.capacitorjs.plugins.firebase.authentication.R; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyResultCallback; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -52,13 +52,12 @@ public void signOut() { new CredentialManagerCallback() { @Override public void onResult(Void result) { - // TODO + // No-op } @Override - public void onError(ClearCredentialException exception) { - // TODO - Logger.error("Error signing out", exception); + public void onError(@NonNull ClearCredentialException exception) { + // No-op } } ); From 80fb9b0aa155a1643b56223c87fadfbf67dd0e69 Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Fri, 24 Jan 2025 09:12:59 +0100 Subject: [PATCH 03/10] wip --- .../handlers/GoogleAuthProviderHandler.java | 71 +++++++++---------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java index c04ecddd..eb6b9a2f 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java @@ -1,17 +1,15 @@ package io.capawesome.capacitorjs.plugins.firebase.authentication.handlers; +import android.os.Bundle; +import androidx.annotation.NonNull; import androidx.credentials.ClearCredentialStateRequest; import androidx.credentials.Credential; import androidx.credentials.CredentialManager; - -import android.os.Bundle; -import androidx.annotation.NonNull; import androidx.credentials.CredentialManagerCallback; import androidx.credentials.GetCredentialRequest; import androidx.credentials.GetCredentialResponse; import androidx.credentials.exceptions.ClearCredentialException; import androidx.credentials.exceptions.GetCredentialException; - import com.getcapacitor.Logger; import com.getcapacitor.PluginCall; import com.google.android.libraries.identity.googleid.GetGoogleIdOption; @@ -21,7 +19,6 @@ import io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthentication; import io.capawesome.capacitorjs.plugins.firebase.authentication.R; import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyResultCallback; - import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -46,20 +43,20 @@ public void signOut() { Executor executor = Executors.newSingleThreadExecutor(); CredentialManager credentialManager = CredentialManager.create(pluginImplementation.getPlugin().getActivity()); credentialManager.clearCredentialStateAsync( - request, - null, - executor, - new CredentialManagerCallback() { - @Override - public void onResult(Void result) { - // No-op - } + request, + null, + executor, + new CredentialManagerCallback() { + @Override + public void onResult(Void result) { + // No-op + } - @Override - public void onError(@NonNull ClearCredentialException exception) { - // No-op - } + @Override + public void onError(@NonNull ClearCredentialException exception) { + // No-op } + } ); } @@ -89,31 +86,29 @@ private void handleGetCredentialResult(final PluginCall call, final boolean isLi public void signInOrLink(final PluginCall call, final boolean isLink) { Executor executor = Executors.newSingleThreadExecutor(); GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder() - // Your server's client ID, not your Android client ID - .setServerClientId(pluginImplementation.getPlugin().getContext().getString(R.string.default_web_client_id)) - // Show all accounts on the device (not just the accounts that have been used previously) - .setFilterByAuthorizedAccounts(false) - .build(); - GetCredentialRequest request = new GetCredentialRequest.Builder() - .addCredentialOption(googleIdOption) - .build(); + // Your server's client ID, not your Android client ID + .setServerClientId(pluginImplementation.getPlugin().getContext().getString(R.string.default_web_client_id)) + // Show all accounts on the device (not just the accounts that have been used previously) + .setFilterByAuthorizedAccounts(false) + .build(); + GetCredentialRequest request = new GetCredentialRequest.Builder().addCredentialOption(googleIdOption).build(); CredentialManager credentialManager = CredentialManager.create(pluginImplementation.getPlugin().getActivity()); credentialManager.getCredentialAsync( - pluginImplementation.getPlugin().getContext(), - request, - null, - executor, - new CredentialManagerCallback() { - @Override - public void onResult(GetCredentialResponse response) { - handleGetCredentialResult(call, isLink, response); - } + pluginImplementation.getPlugin().getContext(), + request, + null, + executor, + new CredentialManagerCallback() { + @Override + public void onResult(GetCredentialResponse response) { + handleGetCredentialResult(call, isLink, response); + } - @Override - public void onError(@NonNull GetCredentialException exception) { - handleGetCredentialError(call, isLink, exception); - } + @Override + public void onError(@NonNull GetCredentialException exception) { + handleGetCredentialError(call, isLink, exception); } + } ); } } From 55941df2d72325889b10280f70c270c9286fb825 Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Fri, 24 Jan 2025 11:19:28 +0100 Subject: [PATCH 04/10] wip --- packages/authentication/BREAKING.md | 7 + .../FirebaseAuthentication.java | 58 +++++-- .../FirebaseAuthenticationPlugin.java | 37 +++-- .../handlers/GoogleAuthProviderHandler.java | 142 +++++++++++++++++- .../handlers/PhoneAuthProviderHandler.java | 8 +- ...tCallback.java => EmptyErrorCallback.java} | 2 +- ...ResultCallback.java => ErrorCallback.java} | 2 +- ...ultCallback.java => NonEmptyCallback.java} | 2 +- .../interfaces/NonEmptyErrorCallback.java | 7 + .../Plugin/FirebaseAuthenticationPlugin.swift | 8 +- 10 files changed, 219 insertions(+), 54 deletions(-) rename packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/{EmptyResultCallback.java => EmptyErrorCallback.java} (61%) rename packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/{ResultCallback.java => ErrorCallback.java} (77%) rename packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/{NonEmptyResultCallback.java => NonEmptyCallback.java} (65%) create mode 100644 packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyErrorCallback.java diff --git a/packages/authentication/BREAKING.md b/packages/authentication/BREAKING.md index f5abaa97..ce88ddb8 100644 --- a/packages/authentication/BREAKING.md +++ b/packages/authentication/BREAKING.md @@ -4,11 +4,18 @@ This is a comprehensive list of the breaking changes introduced in the major ver ## Versions +- [Version 7.x.x](#version-6xx) - [Version 6.x.x](#version-6xx) - [Version 5.x.x](#version-5xx) - [Version 1.x.x](#version-1xx) - [Version 0.4.x](#version-04x) +## Version 7.x.x + +### Google Sign-In + +On **Android**, the `accessToken` and `serverAuthCode` are now only requested when the `scopes` option is set. + ## Version 6.x.x ### Dependencies diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java index e705f7bd..bfbe650a 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java @@ -3,14 +3,21 @@ import static io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthenticationPlugin.ERROR_NO_USER_SIGNED_IN; import static io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthenticationPlugin.TAG; +import android.app.Activity; import android.content.Intent; import android.net.Uri; import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.IntentSenderRequest; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.getcapacitor.JSObject; import com.getcapacitor.Logger; import com.getcapacitor.PluginCall; +import com.google.android.gms.auth.api.identity.AuthorizationResult; +import com.google.android.gms.auth.api.identity.Identity; +import com.google.android.gms.common.api.ApiException; import com.google.android.gms.tasks.Task; import com.google.firebase.auth.ActionCodeSettings; import com.google.firebase.auth.AdditionalUserInfo; @@ -20,7 +27,6 @@ import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; import com.google.firebase.auth.GetTokenResult; -import com.google.firebase.auth.PhoneAuthCredential; import com.google.firebase.auth.UserProfileChangeRequest; import io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthenticationHelper.ProviderId; import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.ConfirmVerificationCodeOptions; @@ -41,10 +47,8 @@ import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.OAuthProviderHandler; import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.PhoneAuthProviderHandler; import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.PlayGamesAuthProviderHandler; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyResultCallback; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyResultCallback; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.Result; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.ResultCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyErrorCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyErrorCallback; import java.util.Arrays; import java.util.List; import org.json.JSONObject; @@ -58,6 +62,7 @@ public class FirebaseAuthentication { private AppleAuthProviderHandler appleAuthProviderHandler; private FacebookAuthProviderHandler facebookAuthProviderHandler; private GoogleAuthProviderHandler googleAuthProviderHandler; + public ActivityResultLauncher googleAuthorizationResultLauncher; private OAuthProviderHandler oAuthProviderHandler; private PhoneAuthProviderHandler phoneAuthProviderHandler; private PlayGamesAuthProviderHandler playGamesAuthProviderHandler; @@ -135,7 +140,7 @@ public void confirmPasswordReset(@NonNull String oobCode, @NonNull String newPas ); } - public void confirmVerificationCode(@NonNull ConfirmVerificationCodeOptions options, @NonNull NonEmptyResultCallback callback) { + public void confirmVerificationCode(@NonNull ConfirmVerificationCodeOptions options, @NonNull NonEmptyErrorCallback callback) { phoneAuthProviderHandler.confirmVerificationCode(options, callback); } @@ -149,7 +154,7 @@ public void deleteUser(FirebaseUser user, @NonNull Runnable callback) { ); } - public void fetchSignInMethodsForEmail(FetchSignInMethodsForEmailOptions options, @NonNull final NonEmptyResultCallback callback) { + public void fetchSignInMethodsForEmail(FetchSignInMethodsForEmailOptions options, @NonNull final NonEmptyErrorCallback callback) { String email = options.getEmail(); getFirebaseAuthInstance() @@ -173,7 +178,7 @@ public FirebaseUser getCurrentUser() { return getFirebaseAuthInstance().getCurrentUser(); } - public void getIdToken(Boolean forceRefresh, @NonNull final NonEmptyResultCallback callback) { + public void getIdToken(Boolean forceRefresh, @NonNull final NonEmptyErrorCallback callback) { FirebaseUser user = getCurrentUser(); if (user == null) { callback.error(new Exception(ERROR_NO_USER_SIGNED_IN)); @@ -327,7 +332,7 @@ public void reload(FirebaseUser user, @NonNull Runnable callback) { ); } - public void revokeAccessToken(@NonNull RevokeAccessTokenOptions options, @NonNull EmptyResultCallback callback) { + public void revokeAccessToken(@NonNull RevokeAccessTokenOptions options, @NonNull EmptyErrorCallback callback) { String token = options.getToken(); getFirebaseAuthInstance() @@ -336,7 +341,7 @@ public void revokeAccessToken(@NonNull RevokeAccessTokenOptions options, @NonNul .addOnFailureListener(exception -> callback.error(exception)); } - public void sendEmailVerification(@NonNull SendEmailVerificationOptions options, @NonNull EmptyResultCallback callback) { + public void sendEmailVerification(@NonNull SendEmailVerificationOptions options, @NonNull EmptyErrorCallback callback) { ActionCodeSettings actionCodeSettings = options.getActionCodeSettings(); FirebaseUser user = getCurrentUser(); @@ -355,7 +360,7 @@ public void sendEmailVerification(@NonNull SendEmailVerificationOptions options, task.addOnSuccessListener(unused -> callback.success()).addOnFailureListener(exception -> callback.error(exception)); } - public void sendPasswordResetEmail(@NonNull SendPasswordResetEmailOptions options, @NonNull EmptyResultCallback callback) { + public void sendPasswordResetEmail(@NonNull SendPasswordResetEmailOptions options, @NonNull EmptyErrorCallback callback) { String email = options.getEmail(); ActionCodeSettings actionCodeSettings = options.getActionCodeSettings(); @@ -597,7 +602,7 @@ public void verifyBeforeUpdateEmail( FirebaseUser user, @NonNull String newEmail, @NonNull ActionCodeSettings actionCodeSettings, - @NonNull EmptyResultCallback callback + @NonNull EmptyErrorCallback callback ) { user .verifyBeforeUpdateEmail(newEmail, actionCodeSettings) @@ -663,7 +668,7 @@ public void handleOnActivityResult(int requestCode, int resultCode, @NonNull Int public void signInWithCredential( @NonNull SignInOptions options, @NonNull AuthCredential credential, - @NonNull NonEmptyResultCallback callback + @NonNull NonEmptyErrorCallback callback ) { boolean skipNativeAuth = options.getSkipNativeAuth(); if (skipNativeAuth) { @@ -689,7 +694,7 @@ public void signInWithCredential( ); } - public void linkWithCredential(@NonNull AuthCredential credential, @NonNull NonEmptyResultCallback callback) { + public void linkWithCredential(@NonNull AuthCredential credential, @NonNull NonEmptyErrorCallback callback) { FirebaseUser user = getFirebaseAuthInstance().getCurrentUser(); if (user == null) { callback.error(new Exception(ERROR_NO_USER_SIGNED_IN)); @@ -882,7 +887,7 @@ public void handleSuccessfulLink(final PluginCall call) { call.resolve(linkResult); } - public void handleFailedLink(final PluginCall call, String message, Exception exception) { + public void handleFailedLink(final PluginCall call, @Nullable String message, Exception exception) { if (message == null && exception != null) { message = exception.getMessage(); } @@ -916,7 +921,7 @@ public FirebaseAuthenticationConfig getConfig() { } private void initAuthProviderHandlers(FirebaseAuthenticationConfig config) { - List providerList = Arrays.asList(config.getProviders()); + List providerList = Arrays.asList(config.getProviders()); if (providerList.contains(ProviderId.APPLE)) { appleAuthProviderHandler = new AppleAuthProviderHandler(this); } @@ -925,6 +930,27 @@ private void initAuthProviderHandlers(FirebaseAuthenticationConfig config) { } if (providerList.contains(ProviderId.GOOGLE)) { googleAuthProviderHandler = new GoogleAuthProviderHandler(this); + googleAuthorizationResultLauncher = + getPlugin() + .getActivity() + .registerForActivityResult( + new ActivityResultContracts.StartIntentSenderForResult(), + result -> { + if (result.getResultCode() == Activity.RESULT_OK) { + Intent intent = result.getData(); + try { + AuthorizationResult authorizationResult = Identity + .getAuthorizationClient(getPlugin().getActivity()) + .getAuthorizationResultFromIntent(intent); + googleAuthProviderHandler.handleAuthorizationResult(authorizationResult); + } catch (ApiException exception) { + googleAuthProviderHandler.handleAuthorizationResultError(exception); + } + } else { + googleAuthProviderHandler.handleAuthorizationResultError(new Exception("Authorization canceled.")); + } + } + ); } if (providerList.contains(ProviderId.PHONE)) { phoneAuthProviderHandler = new PhoneAuthProviderHandler(this); diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java index 8d0df811..1541fbd8 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java @@ -1,7 +1,11 @@ package io.capawesome.capacitorjs.plugins.firebase.authentication; +import android.app.Activity; import android.content.Intent; import androidx.activity.result.ActivityResult; +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.IntentSenderRequest; +import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.getcapacitor.JSObject; @@ -11,6 +15,9 @@ import com.getcapacitor.PluginMethod; import com.getcapacitor.annotation.ActivityCallback; import com.getcapacitor.annotation.CapacitorPlugin; +import com.google.android.gms.auth.api.identity.AuthorizationResult; +import com.google.android.gms.auth.api.identity.Identity; +import com.google.android.gms.common.api.ApiException; import com.google.firebase.auth.ActionCodeSettings; import com.google.firebase.auth.FirebaseUser; import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.ConfirmVerificationCodeOptions; @@ -22,8 +29,8 @@ import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.options.SendEmailVerificationOptions; import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.options.SendPasswordResetEmailOptions; import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.FacebookAuthProviderHandler; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyResultCallback; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyResultCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyErrorCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyErrorCallback; import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.Result; import org.json.JSONObject; @@ -63,6 +70,7 @@ public class FirebaseAuthenticationPlugin extends Plugin { "signInAnonymously cannot be used in combination with skipNativeAuth."; public static final String AUTH_STATE_CHANGE_EVENT = "authStateChange"; public static final String ID_TOKEN_CHANGE_EVENT = "idTokenChange"; + private FirebaseAuthenticationConfig config; private FirebaseAuthentication implementation; @@ -122,7 +130,7 @@ public void confirmVerificationCode(PluginCall call) { return; } ConfirmVerificationCodeOptions options = new ConfirmVerificationCodeOptions(verificationId, verificationCode); - NonEmptyResultCallback callback = new NonEmptyResultCallback() { + NonEmptyErrorCallback callback = new NonEmptyErrorCallback() { @Override public void success(Result result) { call.resolve(result.toJSObject()); @@ -181,7 +189,7 @@ public void fetchSignInMethodsForEmail(PluginCall call) { } FetchSignInMethodsForEmailOptions options = new FetchSignInMethodsForEmailOptions(email); - NonEmptyResultCallback callback = new NonEmptyResultCallback() { + NonEmptyErrorCallback callback = new NonEmptyErrorCallback() { @Override public void success(Result result) { call.resolve(result.toJSObject()); @@ -223,7 +231,7 @@ public void getIdToken(PluginCall call) { try { Boolean forceRefresh = call.getBoolean("forceRefresh", false); - NonEmptyResultCallback callback = new NonEmptyResultCallback() { + NonEmptyErrorCallback callback = new NonEmptyErrorCallback() { @Override public void success(Result result) { call.resolve(result.toJSObject()); @@ -468,7 +476,7 @@ public void revokeAccessToken(PluginCall call) { } RevokeAccessTokenOptions options = new RevokeAccessTokenOptions(token); - EmptyResultCallback callback = new EmptyResultCallback() { + EmptyErrorCallback callback = new EmptyErrorCallback() { @Override public void success() { call.resolve(); @@ -496,7 +504,7 @@ public void sendEmailVerification(PluginCall call) { JSObject actionCodeSettings = call.getObject("actionCodeSettings"); SendEmailVerificationOptions options = new SendEmailVerificationOptions(actionCodeSettings); - EmptyResultCallback callback = new EmptyResultCallback() { + EmptyErrorCallback callback = new EmptyErrorCallback() { @Override public void success() { call.resolve(); @@ -529,7 +537,7 @@ public void sendPasswordResetEmail(PluginCall call) { JSObject actionCodeSettings = call.getObject("actionCodeSettings"); SendPasswordResetEmailOptions options = new SendPasswordResetEmailOptions(email, actionCodeSettings); - EmptyResultCallback callback = new EmptyResultCallback() { + EmptyErrorCallback callback = new EmptyErrorCallback() { @Override public void success() { call.resolve(); @@ -863,7 +871,7 @@ public void verifyBeforeUpdateEmail(PluginCall call) { } ActionCodeSettings actionCodeSettings = FirebaseAuthenticationHelper.createActionCodeSettings(settings); - EmptyResultCallback callback = new EmptyResultCallback() { + EmptyErrorCallback callback = new EmptyErrorCallback() { @Override public void success() { call.resolve(); @@ -986,7 +994,7 @@ public void handleAuthStateChange() { } public void handleIdTokenChange() { - NonEmptyResultCallback callback = new NonEmptyResultCallback() { + NonEmptyErrorCallback callback = new NonEmptyErrorCallback() { @Override public void success(Result result) { notifyListeners(ID_TOKEN_CHANGE_EVENT, result.toJSObject(), true); @@ -1000,15 +1008,6 @@ public void error(Exception exception) { implementation.getIdToken(false, callback); } - @Override - protected void handleOnActivityResult(int requestCode, int resultCode, @Nullable Intent data) { - super.handleOnActivityResult(requestCode, resultCode, data); - if (data == null) { - return; - } - implementation.handleOnActivityResult(requestCode, resultCode, data); - } - @ActivityCallback private void handlePlayGamesAuthProviderSignInActivityResult(@Nullable PluginCall call, @Nullable ActivityResult result) { if (call == null || result == null) { diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java index eb6b9a2f..18e1d745 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java @@ -1,7 +1,12 @@ package io.capawesome.capacitorjs.plugins.firebase.authentication.handlers; +import android.app.PendingIntent; +import android.content.IntentSender; import android.os.Bundle; +import android.util.Log; +import androidx.activity.result.IntentSenderRequest; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.credentials.ClearCredentialStateRequest; import androidx.credentials.Credential; import androidx.credentials.CredentialManager; @@ -10,34 +15,77 @@ import androidx.credentials.GetCredentialResponse; import androidx.credentials.exceptions.ClearCredentialException; import androidx.credentials.exceptions.GetCredentialException; +import com.getcapacitor.JSArray; import com.getcapacitor.Logger; import com.getcapacitor.PluginCall; +import com.google.android.gms.auth.api.identity.AuthorizationRequest; +import com.google.android.gms.auth.api.identity.AuthorizationResult; +import com.google.android.gms.auth.api.identity.Identity; +import com.google.android.gms.common.api.Scope; import com.google.android.libraries.identity.googleid.GetGoogleIdOption; import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential; import com.google.firebase.auth.AuthCredential; import com.google.firebase.auth.GoogleAuthProvider; import io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthentication; +import io.capawesome.capacitorjs.plugins.firebase.authentication.FirebaseAuthenticationPlugin; import io.capawesome.capacitorjs.plugins.firebase.authentication.R; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyResultCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyCallback; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Executor; import java.util.concurrent.Executors; +import org.json.JSONException; public class GoogleAuthProviderHandler { private FirebaseAuthentication pluginImplementation; + private boolean isLastCallLink; + + @Nullable + private AuthCredential lastAuthCredential; + + @Nullable + private PluginCall lastCall; + + @Nullable + private String lastIdToken; public GoogleAuthProviderHandler(FirebaseAuthentication pluginImplementation) { this.pluginImplementation = pluginImplementation; } - public void signIn(final PluginCall call) { - signInOrLink(call, false); + public void handleAuthorizationResult(@NonNull AuthorizationResult authorizationResult) { + if (lastCall == null) { + return; + } + String accessToken = authorizationResult.getAccessToken(); + String serverAuthCode = authorizationResult.getServerAuthCode(); + if (isLastCallLink) { + pluginImplementation.handleSuccessfulLink(lastCall, lastAuthCredential, lastIdToken, null, accessToken, serverAuthCode); + } else { + pluginImplementation.handleSuccessfulSignIn(lastCall, lastAuthCredential, lastIdToken, null, accessToken, serverAuthCode, null); + } + } + + public void handleAuthorizationResultError(@NonNull Exception exception) { + if (lastCall == null) { + return; + } + if (isLastCallLink) { + pluginImplementation.handleFailedLink(lastCall, null, exception); + } else { + pluginImplementation.handleFailedSignIn(lastCall, null, exception); + } } public void link(final PluginCall call) { signInOrLink(call, true); } + public void signIn(final PluginCall call) { + signInOrLink(call, false); + } + public void signOut() { ClearCredentialStateRequest request = new ClearCredentialStateRequest(); Executor executor = Executors.newSingleThreadExecutor(); @@ -60,6 +108,22 @@ public void onError(@NonNull ClearCredentialException exception) { ); } + private List buildScopeList(@NonNull PluginCall call) { + List scopeList = new ArrayList<>(); + JSArray scopes = call.getArray("scopes"); + if (scopes != null) { + try { + List optionArrayElements = scopes.toList(); + for (String optionArrayElement : optionArrayElements) { + scopeList.add(new Scope(optionArrayElement)); + } + } catch (JSONException exception) { + Log.e(FirebaseAuthenticationPlugin.TAG, "Error parsing scopes.", exception); + } + } + return scopeList; + } + private void handleGetCredentialError(final PluginCall call, final boolean isLink, final GetCredentialException exception) { if (isLink) { pluginImplementation.handleFailedLink(call, null, exception); @@ -75,15 +139,44 @@ private void handleGetCredentialResult(final PluginCall call, final boolean isLi GoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(data); String idToken = googleIdTokenCredential.getIdToken(); AuthCredential authCredential = GoogleAuthProvider.getCredential(idToken, null); - if (isLink) { - pluginImplementation.handleSuccessfulLink(call, authCredential, idToken, null, null, null); + List scopes = buildScopeList(call); + if (scopes.isEmpty()) { + if (isLink) { + pluginImplementation.handleSuccessfulLink(call, authCredential, idToken, null, null, null); + } else { + pluginImplementation.handleSuccessfulSignIn(call, authCredential, idToken, null, null, null, null); + } } else { - pluginImplementation.handleSuccessfulSignIn(call, authCredential, idToken, null, null, null, null); + lastAuthCredential = authCredential; + lastCall = call; + lastIdToken = idToken; + requestAuthorizationResult( + scopes, + new NonEmptyCallback() { + @Override + public void success(@NonNull AuthorizationResult result) { + if (isLink) { + pluginImplementation.handleSuccessfulLink(call, authCredential, idToken, null, null, null); + } else { + pluginImplementation.handleSuccessfulSignIn(call, authCredential, idToken, null, null, null, null); + } + } + + @Override + public void error(Exception exception) { + if (isLink) { + pluginImplementation.handleFailedLink(call, null, exception); + } else { + pluginImplementation.handleFailedSignIn(call, null, exception); + } + } + } + ); } } } - public void signInOrLink(final PluginCall call, final boolean isLink) { + private void signInOrLink(final PluginCall call, final boolean isLink) { Executor executor = Executors.newSingleThreadExecutor(); GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder() // Your server's client ID, not your Android client ID @@ -111,4 +204,39 @@ public void onError(@NonNull GetCredentialException exception) { } ); } + + /** + * Request access token and server auth code. + * + * @param scopes The scopes to request. + * @param callback The callback to call with the result. This callback is NOT called if an intent is launched. + */ + private void requestAuthorizationResult(@NonNull final List scopes, @NonNull NonEmptyCallback callback) { + AuthorizationRequest authorizationRequest = AuthorizationRequest + .builder() + .requestOfflineAccess(pluginImplementation.getPlugin().getContext().getString(R.string.default_web_client_id), true) + .setRequestedScopes(scopes) + .build(); + Identity + .getAuthorizationClient(pluginImplementation.getPlugin().getContext()) + .authorize(authorizationRequest) + .addOnSuccessListener( + authorizationResult -> { + if (authorizationResult.hasResolution()) { + // Access needs to be granted by the user + PendingIntent pendingIntent = authorizationResult.getPendingIntent(); + if (pendingIntent == null) { + return; + } + IntentSender intentSender = pendingIntent.getIntentSender(); + IntentSenderRequest intentSenderRequest = new IntentSenderRequest.Builder(intentSender).build(); + pluginImplementation.googleAuthorizationResultLauncher.launch(intentSenderRequest); + } else { + // Access already granted, continue with user action + callback.success(authorizationResult); + } + } + ) + .addOnFailureListener(callback::error); + } } diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/PhoneAuthProviderHandler.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/PhoneAuthProviderHandler.java index 138fe0c7..3511d9bd 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/PhoneAuthProviderHandler.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/PhoneAuthProviderHandler.java @@ -14,9 +14,7 @@ import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.SignInOptions; import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.SignInResult; import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.SignInWithPhoneNumberOptions; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyResultCallback; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.Result; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.ResultCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyErrorCallback; import java.util.concurrent.TimeUnit; public class PhoneAuthProviderHandler { @@ -45,7 +43,7 @@ public void link(@NonNull final LinkWithPhoneNumberOptions options) throws Excep verifyPhoneNumber(options, true); } - public void confirmVerificationCode(@NonNull ConfirmVerificationCodeOptions options, @NonNull NonEmptyResultCallback callback) { + public void confirmVerificationCode(@NonNull ConfirmVerificationCodeOptions options, @NonNull NonEmptyErrorCallback callback) { PhoneAuthCredential credential = PhoneAuthProvider.getCredential(options.getVerificationId(), options.getVerificationCode()); if (signInOnConfirm) { pluginImplementation.signInWithCredential(new SignInOptions(skipNativeAuthOnConfirm), credential, callback); @@ -78,7 +76,7 @@ private PhoneAuthProvider.OnVerificationStateChangedCallbacks createCallbacks( return new PhoneAuthProvider.OnVerificationStateChangedCallbacks() { @Override public void onVerificationCompleted(PhoneAuthCredential credential) { - NonEmptyResultCallback callback = new NonEmptyResultCallback() { + NonEmptyErrorCallback callback = new NonEmptyErrorCallback() { @Override public void success(SignInResult result) { PhoneVerificationCompletedEvent event = new PhoneVerificationCompletedEvent( diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyResultCallback.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyErrorCallback.java similarity index 61% rename from packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyResultCallback.java rename to packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyErrorCallback.java index 57e2f4c8..1f6985ab 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyResultCallback.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyErrorCallback.java @@ -1,5 +1,5 @@ package io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces; -public interface EmptyResultCallback extends ResultCallback { +public interface EmptyErrorCallback extends ErrorCallback { void success(); } diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/ResultCallback.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/ErrorCallback.java similarity index 77% rename from packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/ResultCallback.java rename to packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/ErrorCallback.java index adaee9fb..7c0fd9f3 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/ResultCallback.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/ErrorCallback.java @@ -1,5 +1,5 @@ package io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces; -public interface ResultCallback { +public interface ErrorCallback { void error(Exception exception); } diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyResultCallback.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyCallback.java similarity index 65% rename from packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyResultCallback.java rename to packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyCallback.java index c60d0340..b8008a6f 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyResultCallback.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyCallback.java @@ -2,6 +2,6 @@ import androidx.annotation.NonNull; -public interface NonEmptyResultCallback extends ResultCallback { +public interface NonEmptyCallback extends ErrorCallback { void success(@NonNull T result); } diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyErrorCallback.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyErrorCallback.java new file mode 100644 index 00000000..c5fc15e7 --- /dev/null +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyErrorCallback.java @@ -0,0 +1,7 @@ +package io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces; + +import androidx.annotation.NonNull; + +public interface NonEmptyErrorCallback extends ErrorCallback { + void success(@NonNull T result); +} diff --git a/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift b/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift index cdb04a24..c68ef5f7 100644 --- a/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift +++ b/packages/authentication/ios/Plugin/FirebaseAuthenticationPlugin.swift @@ -10,8 +10,8 @@ import FirebaseAuth // swiftlint:disable type_body_length @objc(FirebaseAuthenticationPlugin) public class FirebaseAuthenticationPlugin: CAPPlugin, CAPBridgedPlugin { - public let identifier = "FirebaseAuthenticationPlugin" - public let jsName = "FirebaseAuthentication" + public let identifier = "FirebaseAuthenticationPlugin" + public let jsName = "FirebaseAuthentication" public let pluginMethods: [CAPPluginMethod] = [ CAPPluginMethod(name: "applyActionCode", returnType: CAPPluginReturnPromise), CAPPluginMethod(name: "confirmPasswordReset", returnType: CAPPluginReturnPromise), @@ -68,8 +68,8 @@ public class FirebaseAuthenticationPlugin: CAPPlugin, CAPBridgedPlugin { CAPPluginMethod(name: "updateProfile", returnType: CAPPluginReturnPromise), CAPPluginMethod(name: "useAppLanguage", returnType: CAPPluginReturnPromise), CAPPluginMethod(name: "useEmulator", returnType: CAPPluginReturnPromise), - CAPPluginMethod(name: "verifyBeforeUpdateEmail", returnType: CAPPluginReturnPromise), - ] + CAPPluginMethod(name: "verifyBeforeUpdateEmail", returnType: CAPPluginReturnPromise) + ] public let tag = "FirebaseAuthentication" public let errorProviderIdMissing = "providerId must be provided." public let errorNoUserSignedIn = "No user is signed in." From 9023621db139868fc6360c8368ee2ec0648ac76e Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Sat, 25 Jan 2025 09:56:41 +0100 Subject: [PATCH 05/10] wip --- .../authentication/FirebaseAuthentication.java | 12 ++++++------ .../FirebaseAuthenticationPlugin.java | 17 +++++------------ .../handlers/PhoneAuthProviderHandler.java | 6 +++--- ...allback.java => NonEmptyResultCallback.java} | 2 +- 4 files changed, 15 insertions(+), 22 deletions(-) rename packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/{NonEmptyErrorCallback.java => NonEmptyResultCallback.java} (65%) diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java index bfbe650a..b469232d 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java @@ -48,7 +48,7 @@ import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.PhoneAuthProviderHandler; import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.PlayGamesAuthProviderHandler; import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyErrorCallback; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyErrorCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyResultCallback; import java.util.Arrays; import java.util.List; import org.json.JSONObject; @@ -140,7 +140,7 @@ public void confirmPasswordReset(@NonNull String oobCode, @NonNull String newPas ); } - public void confirmVerificationCode(@NonNull ConfirmVerificationCodeOptions options, @NonNull NonEmptyErrorCallback callback) { + public void confirmVerificationCode(@NonNull ConfirmVerificationCodeOptions options, @NonNull NonEmptyResultCallback callback) { phoneAuthProviderHandler.confirmVerificationCode(options, callback); } @@ -154,7 +154,7 @@ public void deleteUser(FirebaseUser user, @NonNull Runnable callback) { ); } - public void fetchSignInMethodsForEmail(FetchSignInMethodsForEmailOptions options, @NonNull final NonEmptyErrorCallback callback) { + public void fetchSignInMethodsForEmail(FetchSignInMethodsForEmailOptions options, @NonNull final NonEmptyResultCallback callback) { String email = options.getEmail(); getFirebaseAuthInstance() @@ -178,7 +178,7 @@ public FirebaseUser getCurrentUser() { return getFirebaseAuthInstance().getCurrentUser(); } - public void getIdToken(Boolean forceRefresh, @NonNull final NonEmptyErrorCallback callback) { + public void getIdToken(Boolean forceRefresh, @NonNull final NonEmptyResultCallback callback) { FirebaseUser user = getCurrentUser(); if (user == null) { callback.error(new Exception(ERROR_NO_USER_SIGNED_IN)); @@ -668,7 +668,7 @@ public void handleOnActivityResult(int requestCode, int resultCode, @NonNull Int public void signInWithCredential( @NonNull SignInOptions options, @NonNull AuthCredential credential, - @NonNull NonEmptyErrorCallback callback + @NonNull NonEmptyResultCallback callback ) { boolean skipNativeAuth = options.getSkipNativeAuth(); if (skipNativeAuth) { @@ -694,7 +694,7 @@ public void signInWithCredential( ); } - public void linkWithCredential(@NonNull AuthCredential credential, @NonNull NonEmptyErrorCallback callback) { + public void linkWithCredential(@NonNull AuthCredential credential, @NonNull NonEmptyResultCallback callback) { FirebaseUser user = getFirebaseAuthInstance().getCurrentUser(); if (user == null) { callback.error(new Exception(ERROR_NO_USER_SIGNED_IN)); diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java index 1541fbd8..82d6cf75 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java @@ -1,11 +1,7 @@ package io.capawesome.capacitorjs.plugins.firebase.authentication; -import android.app.Activity; import android.content.Intent; import androidx.activity.result.ActivityResult; -import androidx.activity.result.ActivityResultLauncher; -import androidx.activity.result.IntentSenderRequest; -import androidx.activity.result.contract.ActivityResultContracts; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.getcapacitor.JSObject; @@ -15,9 +11,6 @@ import com.getcapacitor.PluginMethod; import com.getcapacitor.annotation.ActivityCallback; import com.getcapacitor.annotation.CapacitorPlugin; -import com.google.android.gms.auth.api.identity.AuthorizationResult; -import com.google.android.gms.auth.api.identity.Identity; -import com.google.android.gms.common.api.ApiException; import com.google.firebase.auth.ActionCodeSettings; import com.google.firebase.auth.FirebaseUser; import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.ConfirmVerificationCodeOptions; @@ -30,7 +23,7 @@ import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.options.SendPasswordResetEmailOptions; import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.FacebookAuthProviderHandler; import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyErrorCallback; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyErrorCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyResultCallback; import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.Result; import org.json.JSONObject; @@ -130,7 +123,7 @@ public void confirmVerificationCode(PluginCall call) { return; } ConfirmVerificationCodeOptions options = new ConfirmVerificationCodeOptions(verificationId, verificationCode); - NonEmptyErrorCallback callback = new NonEmptyErrorCallback() { + NonEmptyResultCallback callback = new NonEmptyResultCallback() { @Override public void success(Result result) { call.resolve(result.toJSObject()); @@ -189,7 +182,7 @@ public void fetchSignInMethodsForEmail(PluginCall call) { } FetchSignInMethodsForEmailOptions options = new FetchSignInMethodsForEmailOptions(email); - NonEmptyErrorCallback callback = new NonEmptyErrorCallback() { + NonEmptyResultCallback callback = new NonEmptyResultCallback() { @Override public void success(Result result) { call.resolve(result.toJSObject()); @@ -231,7 +224,7 @@ public void getIdToken(PluginCall call) { try { Boolean forceRefresh = call.getBoolean("forceRefresh", false); - NonEmptyErrorCallback callback = new NonEmptyErrorCallback() { + NonEmptyResultCallback callback = new NonEmptyResultCallback() { @Override public void success(Result result) { call.resolve(result.toJSObject()); @@ -994,7 +987,7 @@ public void handleAuthStateChange() { } public void handleIdTokenChange() { - NonEmptyErrorCallback callback = new NonEmptyErrorCallback() { + NonEmptyResultCallback callback = new NonEmptyResultCallback() { @Override public void success(Result result) { notifyListeners(ID_TOKEN_CHANGE_EVENT, result.toJSObject(), true); diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/PhoneAuthProviderHandler.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/PhoneAuthProviderHandler.java index 3511d9bd..2fe06141 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/PhoneAuthProviderHandler.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/PhoneAuthProviderHandler.java @@ -14,7 +14,7 @@ import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.SignInOptions; import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.SignInResult; import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.SignInWithPhoneNumberOptions; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyErrorCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyResultCallback; import java.util.concurrent.TimeUnit; public class PhoneAuthProviderHandler { @@ -43,7 +43,7 @@ public void link(@NonNull final LinkWithPhoneNumberOptions options) throws Excep verifyPhoneNumber(options, true); } - public void confirmVerificationCode(@NonNull ConfirmVerificationCodeOptions options, @NonNull NonEmptyErrorCallback callback) { + public void confirmVerificationCode(@NonNull ConfirmVerificationCodeOptions options, @NonNull NonEmptyResultCallback callback) { PhoneAuthCredential credential = PhoneAuthProvider.getCredential(options.getVerificationId(), options.getVerificationCode()); if (signInOnConfirm) { pluginImplementation.signInWithCredential(new SignInOptions(skipNativeAuthOnConfirm), credential, callback); @@ -76,7 +76,7 @@ private PhoneAuthProvider.OnVerificationStateChangedCallbacks createCallbacks( return new PhoneAuthProvider.OnVerificationStateChangedCallbacks() { @Override public void onVerificationCompleted(PhoneAuthCredential credential) { - NonEmptyErrorCallback callback = new NonEmptyErrorCallback() { + NonEmptyResultCallback callback = new NonEmptyResultCallback() { @Override public void success(SignInResult result) { PhoneVerificationCompletedEvent event = new PhoneVerificationCompletedEvent( diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyErrorCallback.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyResultCallback.java similarity index 65% rename from packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyErrorCallback.java rename to packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyResultCallback.java index c5fc15e7..711e9423 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyErrorCallback.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/NonEmptyResultCallback.java @@ -2,6 +2,6 @@ import androidx.annotation.NonNull; -public interface NonEmptyErrorCallback extends ErrorCallback { +public interface NonEmptyResultCallback extends ErrorCallback { void success(@NonNull T result); } From f44dfa9752faa97a29b117ec4e61eb35bc5023e7 Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Sat, 25 Jan 2025 09:57:24 +0100 Subject: [PATCH 06/10] revert --- .../authentication/FirebaseAuthentication.java | 10 +++++----- .../authentication/FirebaseAuthenticationPlugin.java | 10 +++++----- ...mptyErrorCallback.java => EmptyResultCallback.java} | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) rename packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/{EmptyErrorCallback.java => EmptyResultCallback.java} (62%) diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java index b469232d..01f6096c 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java @@ -47,7 +47,7 @@ import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.OAuthProviderHandler; import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.PhoneAuthProviderHandler; import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.PlayGamesAuthProviderHandler; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyErrorCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyResultCallback; import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyResultCallback; import java.util.Arrays; import java.util.List; @@ -332,7 +332,7 @@ public void reload(FirebaseUser user, @NonNull Runnable callback) { ); } - public void revokeAccessToken(@NonNull RevokeAccessTokenOptions options, @NonNull EmptyErrorCallback callback) { + public void revokeAccessToken(@NonNull RevokeAccessTokenOptions options, @NonNull EmptyResultCallback callback) { String token = options.getToken(); getFirebaseAuthInstance() @@ -341,7 +341,7 @@ public void revokeAccessToken(@NonNull RevokeAccessTokenOptions options, @NonNul .addOnFailureListener(exception -> callback.error(exception)); } - public void sendEmailVerification(@NonNull SendEmailVerificationOptions options, @NonNull EmptyErrorCallback callback) { + public void sendEmailVerification(@NonNull SendEmailVerificationOptions options, @NonNull EmptyResultCallback callback) { ActionCodeSettings actionCodeSettings = options.getActionCodeSettings(); FirebaseUser user = getCurrentUser(); @@ -360,7 +360,7 @@ public void sendEmailVerification(@NonNull SendEmailVerificationOptions options, task.addOnSuccessListener(unused -> callback.success()).addOnFailureListener(exception -> callback.error(exception)); } - public void sendPasswordResetEmail(@NonNull SendPasswordResetEmailOptions options, @NonNull EmptyErrorCallback callback) { + public void sendPasswordResetEmail(@NonNull SendPasswordResetEmailOptions options, @NonNull EmptyResultCallback callback) { String email = options.getEmail(); ActionCodeSettings actionCodeSettings = options.getActionCodeSettings(); @@ -602,7 +602,7 @@ public void verifyBeforeUpdateEmail( FirebaseUser user, @NonNull String newEmail, @NonNull ActionCodeSettings actionCodeSettings, - @NonNull EmptyErrorCallback callback + @NonNull EmptyResultCallback callback ) { user .verifyBeforeUpdateEmail(newEmail, actionCodeSettings) diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java index 82d6cf75..e7b35fe4 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java @@ -22,7 +22,7 @@ import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.options.SendEmailVerificationOptions; import io.capawesome.capacitorjs.plugins.firebase.authentication.classes.options.SendPasswordResetEmailOptions; import io.capawesome.capacitorjs.plugins.firebase.authentication.handlers.FacebookAuthProviderHandler; -import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyErrorCallback; +import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.EmptyResultCallback; import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.NonEmptyResultCallback; import io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces.Result; import org.json.JSONObject; @@ -469,7 +469,7 @@ public void revokeAccessToken(PluginCall call) { } RevokeAccessTokenOptions options = new RevokeAccessTokenOptions(token); - EmptyErrorCallback callback = new EmptyErrorCallback() { + EmptyResultCallback callback = new EmptyResultCallback() { @Override public void success() { call.resolve(); @@ -497,7 +497,7 @@ public void sendEmailVerification(PluginCall call) { JSObject actionCodeSettings = call.getObject("actionCodeSettings"); SendEmailVerificationOptions options = new SendEmailVerificationOptions(actionCodeSettings); - EmptyErrorCallback callback = new EmptyErrorCallback() { + EmptyResultCallback callback = new EmptyResultCallback() { @Override public void success() { call.resolve(); @@ -530,7 +530,7 @@ public void sendPasswordResetEmail(PluginCall call) { JSObject actionCodeSettings = call.getObject("actionCodeSettings"); SendPasswordResetEmailOptions options = new SendPasswordResetEmailOptions(email, actionCodeSettings); - EmptyErrorCallback callback = new EmptyErrorCallback() { + EmptyResultCallback callback = new EmptyResultCallback() { @Override public void success() { call.resolve(); @@ -864,7 +864,7 @@ public void verifyBeforeUpdateEmail(PluginCall call) { } ActionCodeSettings actionCodeSettings = FirebaseAuthenticationHelper.createActionCodeSettings(settings); - EmptyErrorCallback callback = new EmptyErrorCallback() { + EmptyResultCallback callback = new EmptyResultCallback() { @Override public void success() { call.resolve(); diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyErrorCallback.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyResultCallback.java similarity index 62% rename from packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyErrorCallback.java rename to packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyResultCallback.java index 1f6985ab..8c49ff61 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyErrorCallback.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/interfaces/EmptyResultCallback.java @@ -1,5 +1,5 @@ package io.capawesome.capacitorjs.plugins.firebase.authentication.interfaces; -public interface EmptyErrorCallback extends ErrorCallback { +public interface EmptyResultCallback extends ErrorCallback { void success(); } From 249a70581b170f76aa0a2beac61b769f5c8099fd Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Sat, 25 Jan 2025 10:00:51 +0100 Subject: [PATCH 07/10] wip --- .../FirebaseAuthentication.java | 16 +-------------- .../handlers/GoogleAuthProviderHandler.java | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java index 01f6096c..41686f77 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthentication.java @@ -935,21 +935,7 @@ private void initAuthProviderHandlers(FirebaseAuthenticationConfig config) { .getActivity() .registerForActivityResult( new ActivityResultContracts.StartIntentSenderForResult(), - result -> { - if (result.getResultCode() == Activity.RESULT_OK) { - Intent intent = result.getData(); - try { - AuthorizationResult authorizationResult = Identity - .getAuthorizationClient(getPlugin().getActivity()) - .getAuthorizationResultFromIntent(intent); - googleAuthProviderHandler.handleAuthorizationResult(authorizationResult); - } catch (ApiException exception) { - googleAuthProviderHandler.handleAuthorizationResultError(exception); - } - } else { - googleAuthProviderHandler.handleAuthorizationResultError(new Exception("Authorization canceled.")); - } - } + result -> googleAuthProviderHandler.handleActivityResult(result) ); } if (providerList.contains(ProviderId.PHONE)) { diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java index 18e1d745..b54c6aa6 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java @@ -1,9 +1,12 @@ package io.capawesome.capacitorjs.plugins.firebase.authentication.handlers; +import android.app.Activity; import android.app.PendingIntent; +import android.content.Intent; import android.content.IntentSender; import android.os.Bundle; import android.util.Log; +import androidx.activity.result.ActivityResult; import androidx.activity.result.IntentSenderRequest; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -21,6 +24,7 @@ import com.google.android.gms.auth.api.identity.AuthorizationRequest; import com.google.android.gms.auth.api.identity.AuthorizationResult; import com.google.android.gms.auth.api.identity.Identity; +import com.google.android.gms.common.api.ApiException; import com.google.android.gms.common.api.Scope; import com.google.android.libraries.identity.googleid.GetGoogleIdOption; import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential; @@ -54,6 +58,22 @@ public GoogleAuthProviderHandler(FirebaseAuthentication pluginImplementation) { this.pluginImplementation = pluginImplementation; } + public void handleActivityResult(@NonNull ActivityResult result) { + if (result.getResultCode() == Activity.RESULT_OK) { + Intent intent = result.getData(); + try { + AuthorizationResult authorizationResult = Identity + .getAuthorizationClient(pluginImplementation.getPlugin().getActivity()) + .getAuthorizationResultFromIntent(intent); + handleAuthorizationResult(authorizationResult); + } catch (ApiException exception) { + handleAuthorizationResultError(exception); + } + } else { + handleAuthorizationResultError(new Exception("Authorization canceled.")); + } + } + public void handleAuthorizationResult(@NonNull AuthorizationResult authorizationResult) { if (lastCall == null) { return; From b0b7602508700dba9652562124d7d6ff76859d65 Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Sat, 25 Jan 2025 10:01:54 +0100 Subject: [PATCH 08/10] revert --- .../authentication/FirebaseAuthenticationPlugin.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java index e7b35fe4..f4832057 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/FirebaseAuthenticationPlugin.java @@ -1001,6 +1001,15 @@ public void error(Exception exception) { implementation.getIdToken(false, callback); } + @Override + protected void handleOnActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.handleOnActivityResult(requestCode, resultCode, data); + if (data == null) { + return; + } + implementation.handleOnActivityResult(requestCode, resultCode, data); + } + @ActivityCallback private void handlePlayGamesAuthProviderSignInActivityResult(@Nullable PluginCall call, @Nullable ActivityResult result) { if (call == null || result == null) { From 7a5462dbb8758ef729bd535f36f9e0d4a2736853 Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Sat, 25 Jan 2025 10:10:07 +0100 Subject: [PATCH 09/10] wip --- .../handlers/GoogleAuthProviderHandler.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java index b54c6aa6..80f3720d 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java @@ -43,16 +43,13 @@ public class GoogleAuthProviderHandler { private FirebaseAuthentication pluginImplementation; - private boolean isLastCallLink; - @Nullable private AuthCredential lastAuthCredential; - @Nullable private PluginCall lastCall; - @Nullable private String lastIdToken; + private boolean wasLink = false; public GoogleAuthProviderHandler(FirebaseAuthentication pluginImplementation) { this.pluginImplementation = pluginImplementation; @@ -80,22 +77,28 @@ public void handleAuthorizationResult(@NonNull AuthorizationResult authorization } String accessToken = authorizationResult.getAccessToken(); String serverAuthCode = authorizationResult.getServerAuthCode(); - if (isLastCallLink) { + if (wasLink) { pluginImplementation.handleSuccessfulLink(lastCall, lastAuthCredential, lastIdToken, null, accessToken, serverAuthCode); } else { pluginImplementation.handleSuccessfulSignIn(lastCall, lastAuthCredential, lastIdToken, null, accessToken, serverAuthCode, null); } + lastAuthCredential = null; + lastCall = null; + lastIdToken = null; } public void handleAuthorizationResultError(@NonNull Exception exception) { if (lastCall == null) { return; } - if (isLastCallLink) { + if (wasLink) { pluginImplementation.handleFailedLink(lastCall, null, exception); } else { pluginImplementation.handleFailedSignIn(lastCall, null, exception); } + lastAuthCredential = null; + lastCall = null; + lastIdToken = null; } public void link(final PluginCall call) { @@ -170,6 +173,7 @@ private void handleGetCredentialResult(final PluginCall call, final boolean isLi lastAuthCredential = authCredential; lastCall = call; lastIdToken = idToken; + wasLink = isLink; requestAuthorizationResult( scopes, new NonEmptyCallback() { @@ -229,7 +233,7 @@ public void onError(@NonNull GetCredentialException exception) { * Request access token and server auth code. * * @param scopes The scopes to request. - * @param callback The callback to call with the result. This callback is NOT called if an intent is launched. + * @param callback The callback to call with the result. This callback is NOT called if an intent is launched. */ private void requestAuthorizationResult(@NonNull final List scopes, @NonNull NonEmptyCallback callback) { AuthorizationRequest authorizationRequest = AuthorizationRequest From 3df23ff50df3ccbe9cdff586e29222fdb16f1713 Mon Sep 17 00:00:00 2001 From: Robin Genz Date: Sat, 25 Jan 2025 10:11:36 +0100 Subject: [PATCH 10/10] style: format --- .../authentication/handlers/GoogleAuthProviderHandler.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java index 80f3720d..b02b64fa 100644 --- a/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java +++ b/packages/authentication/android/src/main/java/io/capawesome/capacitorjs/plugins/firebase/authentication/handlers/GoogleAuthProviderHandler.java @@ -43,12 +43,16 @@ public class GoogleAuthProviderHandler { private FirebaseAuthentication pluginImplementation; + @Nullable private AuthCredential lastAuthCredential; + @Nullable private PluginCall lastCall; + @Nullable private String lastIdToken; + private boolean wasLink = false; public GoogleAuthProviderHandler(FirebaseAuthentication pluginImplementation) {