Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,9 @@

import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
import com.google.android.gms.tasks.OnCompleteListener;
Expand All@@ -22,19 +24,20 @@

import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AnonymousUpgradeActivity extends AppCompatActivity {
public class AnonymousUpgradeActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {

private static final String TAG = "AccountLink";

private static final int RC_SIGN_IN = 123;

@BindView(R.id.status_text)
TextView mStatus;

Expand All@@ -52,6 +55,9 @@ public class AnonymousUpgradeActivity extends AppCompatActivity {

private AuthCredential mPendingCredential;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All@@ -64,8 +70,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Occurs after catching an email link
IdpResponse response = IdpResponse.fromResultIntent(getIntent());
if (response != null) {
handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
getIntent());
handleSignInResult(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, response);
}
}

Expand All@@ -90,12 +95,12 @@ public void onComplete(@NonNull Task<AuthResult> task) {
@OnClick(R.id.begin_flow)
public void startAuthUI() {
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
Intent signInIntent = AuthUI.getInstance().createSignInIntentBuilder()
.setLogo(R.drawable.firebase_auth_120dp)
.setAvailableProviders(providers)
.enableAnonymousUsersAutoUpgrade()
.build();
startActivityForResult(intent, RC_SIGN_IN);
signIn.launch(signInIntent);
}

@OnClick(R.id.resolve_merge)
Expand DownExpand Up@@ -137,34 +142,25 @@ public void onComplete(@NonNull Task<Void> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
handleSignInResult(requestCode, resultCode, data);
}

private void handleSignInResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
private void handleSignInResult(int resultCode, @Nullable IdpResponse response) {
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
}

private void updateUI() {
Expand DownExpand Up@@ -212,4 +208,9 @@ private String getUserIdentifier(FirebaseUser user) {
return "unknown";
}
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
handleSignInResult(result.getResultCode(), result.getIdpResponse());
}
}
39 changes: 20 additions & 19 deletions app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,6 +31,8 @@
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.ui.auth.util.ExtraConstants;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
Expand All@@ -45,6 +47,8 @@
import java.util.ArrayList;
import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All@@ -56,7 +60,8 @@
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AuthUiActivity extends AppCompatActivity {
public class AuthUiActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {
private static final String TAG = "AuthUiActivity";

private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/";
Expand All@@ -66,8 +71,6 @@ public class AuthUiActivity extends AppCompatActivity {
private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google" +
".com/terms/analytics/#7_privacy";

private static final int RC_SIGN_IN = 100;

@BindView(R.id.root) View mRootView;

@BindView(R.id.google_provider) CheckBox mUseGoogleProvider;
Expand DownExpand Up@@ -111,6 +114,9 @@ public class AuthUiActivity extends AppCompatActivity {
@BindView(R.id.require_name) CheckBox mRequireName;
@BindView(R.id.use_auth_emulator) CheckBox mUseEmulator;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@NonNull
public static Intent createIntent(@NonNull Context context) {
return new Intent(context, AuthUiActivity.class);
Expand DownExpand Up@@ -237,11 +243,11 @@ public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) {

@OnClick(R.id.sign_in)
public void signIn() {
startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN);
signIn.launch(getSignInIntent(/*link=*/null));
}

public void signInWithEmailLink(@Nullable String link) {
startActivityForResult(buildSignInIntent(link), RC_SIGN_IN);
signIn.launch(getSignInIntent(link));
}

@NonNull
Expand All@@ -254,8 +260,7 @@ public AuthUI getAuthUI() {
return authUI;
}

@NonNull
public Intent buildSignInIntent(@Nullable String link) {
private Intent getSignInIntent(@Nullable String link) {
AuthUI.SignInIntentBuilder builder = getAuthUI().createSignInIntentBuilder()
.setTheme(getSelectedTheme())
.setLogo(getSelectedLogo())
Expand DownExpand Up@@ -290,7 +295,6 @@ public Intent buildSignInIntent(@Nullable String link) {
if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) {
builder.enableAnonymousUsersAutoUpgrade();
}

return builder.build();
}

Expand All@@ -309,14 +313,6 @@ public void onComplete(@NonNull Task<AuthResult> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
handleSignInResponse(resultCode, data);
}
}

@Override
protected void onResume() {
super.onResume();
Expand All@@ -327,9 +323,7 @@ protected void onResume() {
}
}

private void handleSignInResponse(int resultCode, @Nullable Intent data) {
IdpResponse response = IdpResponse.fromResultIntent(data);

private void handleSignInResponse(int resultCode, @Nullable IdpResponse response) {
// Successfully signed in
if (resultCode == RESULT_OK) {
startSignedInActivity(response);
Expand DownExpand Up@@ -529,4 +523,11 @@ private List<String> getFacebookPermissions() {
private void showSnackbar(@StringRes int errorMessageRes) {
Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG).show();
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
// Successfully signed in
IdpResponse response = result.getIdpResponse();
handleSignInResponse(result.getResultCode(), response);
}
}
4 changes: 4 additions & 0 deletions auth/build.gradle.kts
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,10 @@ android {
}

dependencies {
implementation(Config.Libs.Androidx.activity)
// The new activity result APIs force us to include Fragment 1.3.0
// See https://issuetracker.google.com/issues/152554847
implementation(Config.Libs.Androidx.fragment)
implementation(Config.Libs.Androidx.design)
implementation(Config.Libs.Androidx.customTabs)
implementation(Config.Libs.Androidx.constraint)
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
package com.firebase.ui.auth;

import android.content.Context;
import android.content.Intent;

import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;

import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* A {@link ActivityResultContract} describing that the caller can launch authentication flow with a
* {@link Intent} and is guaranteed to receive a {@link FirebaseAuthUIAuthenticationResult} as
* result. The given input intent <b>must</b> be created using a
* {@link com.firebase.ui.auth.AuthUI.SignInIntentBuilder} in order to guarantee a successful
* launch of the authentication flow.
*/
public class FirebaseAuthUIActivityResultContract extends
ActivityResultContract<Intent, FirebaseAuthUIAuthenticationResult> {

@NonNull
@Override
public Intent createIntent(@NonNull Context context, Intent input) {
return input;
}

@Override
@NonNull
public FirebaseAuthUIAuthenticationResult parseResult(int resultCode, @Nullable Intent intent) {
return new FirebaseAuthUIAuthenticationResult(resultCode, IdpResponse.fromResultIntent(intent));
}

}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
package com.firebase.ui.auth.data.model;

import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* Result of launching a {@link FirebaseAuthUIActivityResultContract}
*/
public class FirebaseAuthUIAuthenticationResult {

@Nullable
private final IdpResponse idpResponse;
@NonNull
private final Integer resultCode;

public FirebaseAuthUIAuthenticationResult(@NonNull Integer resultCode, @Nullable IdpResponse idpResponse) {
this.idpResponse = idpResponse;
this.resultCode = resultCode;
}

/**
* The contained {@link IdpResponse} returned from the Firebase library
*/
@Nullable
public IdpResponse getIdpResponse() {
return idpResponse;
}

/**
* The result code of the received activity result
*
* @see android.app.Activity.RESULT_CANCELED
* @see android.app.Activity.RESULT_OK
*/
@NonNull
public Integer getResultCode() {
return resultCode;
}

@Override
public int hashCode() {
int result = idpResponse == null ? 0 : idpResponse.hashCode();
result = 31 * result + resultCode.hashCode();
return result;
}

@Override
public String toString() {
return "FirebaseAuthUIAuthenticationResult{" +
"idpResponse=" + idpResponse +
", resultCode='" + resultCode +
'}';
}
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Config.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,9 +26,11 @@ object Config {

object Androidx {
const val annotations = "androidx.annotation:annotation:1.1.0"
const val activity = "androidx.activity:activity:1.2.0"
const val customTabs = "androidx.browser:browser:1.0.0"
const val cardView = "androidx.cardview:cardview:1.0.0"
const val constraint = "androidx.constraintlayout:constraintlayout:2.0.4"
const val fragment = "androidx.fragment:fragment:1.3.0"
const val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:2.2.0"
const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:2.2.0"
const val lifecycleRuntime = "androidx.lifecycle:lifecycle-runtime:2.2.0"
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,9 @@

import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
import com.google.android.gms.tasks.OnCompleteListener;
Expand All@@ -22,19 +24,20 @@

import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AnonymousUpgradeActivity extends AppCompatActivity {
public class AnonymousUpgradeActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {

private static final String TAG = "AccountLink";

private static final int RC_SIGN_IN = 123;

@BindView(R.id.status_text)
TextView mStatus;

Expand All@@ -52,6 +55,9 @@ public class AnonymousUpgradeActivity extends AppCompatActivity {

private AuthCredential mPendingCredential;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All@@ -64,8 +70,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Occurs after catching an email link
IdpResponse response = IdpResponse.fromResultIntent(getIntent());
if (response != null) {
handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
getIntent());
handleSignInResult(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, response);
}
}

Expand All@@ -90,12 +95,12 @@ public void onComplete(@NonNull Task<AuthResult> task) {
@OnClick(R.id.begin_flow)
public void startAuthUI() {
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
Intent signInIntent = AuthUI.getInstance().createSignInIntentBuilder()
.setLogo(R.drawable.firebase_auth_120dp)
.setAvailableProviders(providers)
.enableAnonymousUsersAutoUpgrade()
.build();
startActivityForResult(intent, RC_SIGN_IN);
signIn.launch(signInIntent);
}

@OnClick(R.id.resolve_merge)
Expand DownExpand Up@@ -137,34 +142,25 @@ public void onComplete(@NonNull Task<Void> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
handleSignInResult(requestCode, resultCode, data);
}

private void handleSignInResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
private void handleSignInResult(int resultCode, @Nullable IdpResponse response) {
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
}

private void updateUI() {
Expand DownExpand Up@@ -212,4 +208,9 @@ private String getUserIdentifier(FirebaseUser user) {
return "unknown";
}
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
handleSignInResult(result.getResultCode(), result.getIdpResponse());
}
}
39 changes: 20 additions & 19 deletions app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,6 +31,8 @@
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.ui.auth.util.ExtraConstants;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
Expand All@@ -45,6 +47,8 @@
import java.util.ArrayList;
import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All@@ -56,7 +60,8 @@
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AuthUiActivity extends AppCompatActivity {
public class AuthUiActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {
private static final String TAG = "AuthUiActivity";

private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/";
Expand All@@ -66,8 +71,6 @@ public class AuthUiActivity extends AppCompatActivity {
private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google" +
".com/terms/analytics/#7_privacy";

private static final int RC_SIGN_IN = 100;

@BindView(R.id.root) View mRootView;

@BindView(R.id.google_provider) CheckBox mUseGoogleProvider;
Expand DownExpand Up@@ -111,6 +114,9 @@ public class AuthUiActivity extends AppCompatActivity {
@BindView(R.id.require_name) CheckBox mRequireName;
@BindView(R.id.use_auth_emulator) CheckBox mUseEmulator;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@NonNull
public static Intent createIntent(@NonNull Context context) {
return new Intent(context, AuthUiActivity.class);
Expand DownExpand Up@@ -237,11 +243,11 @@ public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) {

@OnClick(R.id.sign_in)
public void signIn() {
startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN);
signIn.launch(getSignInIntent(/*link=*/null));
}

public void signInWithEmailLink(@Nullable String link) {
startActivityForResult(buildSignInIntent(link), RC_SIGN_IN);
signIn.launch(getSignInIntent(link));
}

@NonNull
Expand All@@ -254,8 +260,7 @@ public AuthUI getAuthUI() {
return authUI;
}

@NonNull
public Intent buildSignInIntent(@Nullable String link) {
private Intent getSignInIntent(@Nullable String link) {
AuthUI.SignInIntentBuilder builder = getAuthUI().createSignInIntentBuilder()
.setTheme(getSelectedTheme())
.setLogo(getSelectedLogo())
Expand DownExpand Up@@ -290,7 +295,6 @@ public Intent buildSignInIntent(@Nullable String link) {
if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) {
builder.enableAnonymousUsersAutoUpgrade();
}

return builder.build();
}

Expand All@@ -309,14 +313,6 @@ public void onComplete(@NonNull Task<AuthResult> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
handleSignInResponse(resultCode, data);
}
}

@Override
protected void onResume() {
super.onResume();
Expand All@@ -327,9 +323,7 @@ protected void onResume() {
}
}

private void handleSignInResponse(int resultCode, @Nullable Intent data) {
IdpResponse response = IdpResponse.fromResultIntent(data);

private void handleSignInResponse(int resultCode, @Nullable IdpResponse response) {
// Successfully signed in
if (resultCode == RESULT_OK) {
startSignedInActivity(response);
Expand DownExpand Up@@ -529,4 +523,11 @@ private List<String> getFacebookPermissions() {
private void showSnackbar(@StringRes int errorMessageRes) {
Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG).show();
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
// Successfully signed in
IdpResponse response = result.getIdpResponse();
handleSignInResponse(result.getResultCode(), response);
}
}
4 changes: 4 additions & 0 deletions auth/build.gradle.kts
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,10 @@ android {
}

dependencies {
implementation(Config.Libs.Androidx.activity)
// The new activity result APIs force us to include Fragment 1.3.0
// See https://issuetracker.google.com/issues/152554847
implementation(Config.Libs.Androidx.fragment)
implementation(Config.Libs.Androidx.design)
implementation(Config.Libs.Androidx.customTabs)
implementation(Config.Libs.Androidx.constraint)
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
package com.firebase.ui.auth;

import android.content.Context;
import android.content.Intent;

import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;

import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* A {@link ActivityResultContract} describing that the caller can launch authentication flow with a
* {@link Intent} and is guaranteed to receive a {@link FirebaseAuthUIAuthenticationResult} as
* result. The given input intent <b>must</b> be created using a
* {@link com.firebase.ui.auth.AuthUI.SignInIntentBuilder} in order to guarantee a successful
* launch of the authentication flow.
*/
public class FirebaseAuthUIActivityResultContract extends
ActivityResultContract<Intent, FirebaseAuthUIAuthenticationResult> {

@NonNull
@Override
public Intent createIntent(@NonNull Context context, Intent input) {
return input;
}

@Override
@NonNull
public FirebaseAuthUIAuthenticationResult parseResult(int resultCode, @Nullable Intent intent) {
return new FirebaseAuthUIAuthenticationResult(resultCode, IdpResponse.fromResultIntent(intent));
}

}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
package com.firebase.ui.auth.data.model;

import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* Result of launching a {@link FirebaseAuthUIActivityResultContract}
*/
public class FirebaseAuthUIAuthenticationResult {

@Nullable
private final IdpResponse idpResponse;
@NonNull
private final Integer resultCode;

public FirebaseAuthUIAuthenticationResult(@NonNull Integer resultCode, @Nullable IdpResponse idpResponse) {
this.idpResponse = idpResponse;
this.resultCode = resultCode;
}

/**
* The contained {@link IdpResponse} returned from the Firebase library
*/
@Nullable
public IdpResponse getIdpResponse() {
return idpResponse;
}

/**
* The result code of the received activity result
*
* @see android.app.Activity.RESULT_CANCELED
* @see android.app.Activity.RESULT_OK
*/
@NonNull
public Integer getResultCode() {
return resultCode;
}

@Override
public int hashCode() {
int result = idpResponse == null ? 0 : idpResponse.hashCode();
result = 31 * result + resultCode.hashCode();
return result;
}

@Override
public String toString() {
return "FirebaseAuthUIAuthenticationResult{" +
"idpResponse=" + idpResponse +
", resultCode='" + resultCode +
'}';
}
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Config.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,9 +26,11 @@ object Config {

object Androidx {
const val annotations = "androidx.annotation:annotation:1.1.0"
const val activity = "androidx.activity:activity:1.2.0"
const val customTabs = "androidx.browser:browser:1.0.0"
const val cardView = "androidx.cardview:cardview:1.0.0"
const val constraint = "androidx.constraintlayout:constraintlayout:2.0.4"
const val fragment = "androidx.fragment:fragment:1.3.0"
const val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:2.2.0"
const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:2.2.0"
const val lifecycleRuntime = "androidx.lifecycle:lifecycle-runtime:2.2.0"
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,9 @@

import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
import com.google.android.gms.tasks.OnCompleteListener;
Expand All@@ -22,19 +24,20 @@

import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AnonymousUpgradeActivity extends AppCompatActivity {
public class AnonymousUpgradeActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {

private static final String TAG = "AccountLink";

private static final int RC_SIGN_IN = 123;

@BindView(R.id.status_text)
TextView mStatus;

Expand All@@ -52,6 +55,9 @@ public class AnonymousUpgradeActivity extends AppCompatActivity {

private AuthCredential mPendingCredential;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All@@ -64,8 +70,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Occurs after catching an email link
IdpResponse response = IdpResponse.fromResultIntent(getIntent());
if (response != null) {
handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
getIntent());
handleSignInResult(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, response);
}
}

Expand All@@ -90,12 +95,12 @@ public void onComplete(@NonNull Task<AuthResult> task) {
@OnClick(R.id.begin_flow)
public void startAuthUI() {
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
Intent signInIntent = AuthUI.getInstance().createSignInIntentBuilder()
.setLogo(R.drawable.firebase_auth_120dp)
.setAvailableProviders(providers)
.enableAnonymousUsersAutoUpgrade()
.build();
startActivityForResult(intent, RC_SIGN_IN);
signIn.launch(signInIntent);
}

@OnClick(R.id.resolve_merge)
Expand DownExpand Up@@ -137,34 +142,25 @@ public void onComplete(@NonNull Task<Void> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
handleSignInResult(requestCode, resultCode, data);
}

private void handleSignInResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
private void handleSignInResult(int resultCode, @Nullable IdpResponse response) {
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
}

private void updateUI() {
Expand DownExpand Up@@ -212,4 +208,9 @@ private String getUserIdentifier(FirebaseUser user) {
return "unknown";
}
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
handleSignInResult(result.getResultCode(), result.getIdpResponse());
}
}
39 changes: 20 additions & 19 deletions app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,6 +31,8 @@
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.ui.auth.util.ExtraConstants;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
Expand All@@ -45,6 +47,8 @@
import java.util.ArrayList;
import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All@@ -56,7 +60,8 @@
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AuthUiActivity extends AppCompatActivity {
public class AuthUiActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {
private static final String TAG = "AuthUiActivity";

private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/";
Expand All@@ -66,8 +71,6 @@ public class AuthUiActivity extends AppCompatActivity {
private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google" +
".com/terms/analytics/#7_privacy";

private static final int RC_SIGN_IN = 100;

@BindView(R.id.root) View mRootView;

@BindView(R.id.google_provider) CheckBox mUseGoogleProvider;
Expand DownExpand Up@@ -111,6 +114,9 @@ public class AuthUiActivity extends AppCompatActivity {
@BindView(R.id.require_name) CheckBox mRequireName;
@BindView(R.id.use_auth_emulator) CheckBox mUseEmulator;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@NonNull
public static Intent createIntent(@NonNull Context context) {
return new Intent(context, AuthUiActivity.class);
Expand DownExpand Up@@ -237,11 +243,11 @@ public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) {

@OnClick(R.id.sign_in)
public void signIn() {
startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN);
signIn.launch(getSignInIntent(/*link=*/null));
}

public void signInWithEmailLink(@Nullable String link) {
startActivityForResult(buildSignInIntent(link), RC_SIGN_IN);
signIn.launch(getSignInIntent(link));
}

@NonNull
Expand All@@ -254,8 +260,7 @@ public AuthUI getAuthUI() {
return authUI;
}

@NonNull
public Intent buildSignInIntent(@Nullable String link) {
private Intent getSignInIntent(@Nullable String link) {
AuthUI.SignInIntentBuilder builder = getAuthUI().createSignInIntentBuilder()
.setTheme(getSelectedTheme())
.setLogo(getSelectedLogo())
Expand DownExpand Up@@ -290,7 +295,6 @@ public Intent buildSignInIntent(@Nullable String link) {
if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) {
builder.enableAnonymousUsersAutoUpgrade();
}

return builder.build();
}

Expand All@@ -309,14 +313,6 @@ public void onComplete(@NonNull Task<AuthResult> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
handleSignInResponse(resultCode, data);
}
}

@Override
protected void onResume() {
super.onResume();
Expand All@@ -327,9 +323,7 @@ protected void onResume() {
}
}

private void handleSignInResponse(int resultCode, @Nullable Intent data) {
IdpResponse response = IdpResponse.fromResultIntent(data);

private void handleSignInResponse(int resultCode, @Nullable IdpResponse response) {
// Successfully signed in
if (resultCode == RESULT_OK) {
startSignedInActivity(response);
Expand DownExpand Up@@ -529,4 +523,11 @@ private List<String> getFacebookPermissions() {
private void showSnackbar(@StringRes int errorMessageRes) {
Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG).show();
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
// Successfully signed in
IdpResponse response = result.getIdpResponse();
handleSignInResponse(result.getResultCode(), response);
}
}
4 changes: 4 additions & 0 deletions auth/build.gradle.kts
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,10 @@ android {
}

dependencies {
implementation(Config.Libs.Androidx.activity)
// The new activity result APIs force us to include Fragment 1.3.0
// See https://issuetracker.google.com/issues/152554847
implementation(Config.Libs.Androidx.fragment)
implementation(Config.Libs.Androidx.design)
implementation(Config.Libs.Androidx.customTabs)
implementation(Config.Libs.Androidx.constraint)
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
package com.firebase.ui.auth;

import android.content.Context;
import android.content.Intent;

import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;

import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* A {@link ActivityResultContract} describing that the caller can launch authentication flow with a
* {@link Intent} and is guaranteed to receive a {@link FirebaseAuthUIAuthenticationResult} as
* result. The given input intent <b>must</b> be created using a
* {@link com.firebase.ui.auth.AuthUI.SignInIntentBuilder} in order to guarantee a successful
* launch of the authentication flow.
*/
public class FirebaseAuthUIActivityResultContract extends
ActivityResultContract<Intent, FirebaseAuthUIAuthenticationResult> {

@NonNull
@Override
public Intent createIntent(@NonNull Context context, Intent input) {
return input;
}

@Override
@NonNull
public FirebaseAuthUIAuthenticationResult parseResult(int resultCode, @Nullable Intent intent) {
return new FirebaseAuthUIAuthenticationResult(resultCode, IdpResponse.fromResultIntent(intent));
}

}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
package com.firebase.ui.auth.data.model;

import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* Result of launching a {@link FirebaseAuthUIActivityResultContract}
*/
public class FirebaseAuthUIAuthenticationResult {

@Nullable
private final IdpResponse idpResponse;
@NonNull
private final Integer resultCode;

public FirebaseAuthUIAuthenticationResult(@NonNull Integer resultCode, @Nullable IdpResponse idpResponse) {
this.idpResponse = idpResponse;
this.resultCode = resultCode;
}

/**
* The contained {@link IdpResponse} returned from the Firebase library
*/
@Nullable
public IdpResponse getIdpResponse() {
return idpResponse;
}

/**
* The result code of the received activity result
*
* @see android.app.Activity.RESULT_CANCELED
* @see android.app.Activity.RESULT_OK
*/
@NonNull
public Integer getResultCode() {
return resultCode;
}

@Override
public int hashCode() {
int result = idpResponse == null ? 0 : idpResponse.hashCode();
result = 31 * result + resultCode.hashCode();
return result;
}

@Override
public String toString() {
return "FirebaseAuthUIAuthenticationResult{" +
"idpResponse=" + idpResponse +
", resultCode='" + resultCode +
'}';
}
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Config.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,9 +26,11 @@ object Config {

object Androidx {
const val annotations = "androidx.annotation:annotation:1.1.0"
const val activity = "androidx.activity:activity:1.2.0"
const val customTabs = "androidx.browser:browser:1.0.0"
const val cardView = "androidx.cardview:cardview:1.0.0"
const val constraint = "androidx.constraintlayout:constraintlayout:2.0.4"
const val fragment = "androidx.fragment:fragment:1.3.0"
const val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:2.2.0"
const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:2.2.0"
const val lifecycleRuntime = "androidx.lifecycle:lifecycle-runtime:2.2.0"
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,9 @@

import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
import com.google.android.gms.tasks.OnCompleteListener;
Expand All@@ -22,19 +24,20 @@

import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AnonymousUpgradeActivity extends AppCompatActivity {
public class AnonymousUpgradeActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {

private static final String TAG = "AccountLink";

private static final int RC_SIGN_IN = 123;

@BindView(R.id.status_text)
TextView mStatus;

Expand All@@ -52,6 +55,9 @@ public class AnonymousUpgradeActivity extends AppCompatActivity {

private AuthCredential mPendingCredential;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All@@ -64,8 +70,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Occurs after catching an email link
IdpResponse response = IdpResponse.fromResultIntent(getIntent());
if (response != null) {
handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
getIntent());
handleSignInResult(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, response);
}
}

Expand All@@ -90,12 +95,12 @@ public void onComplete(@NonNull Task<AuthResult> task) {
@OnClick(R.id.begin_flow)
public void startAuthUI() {
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
Intent signInIntent = AuthUI.getInstance().createSignInIntentBuilder()
.setLogo(R.drawable.firebase_auth_120dp)
.setAvailableProviders(providers)
.enableAnonymousUsersAutoUpgrade()
.build();
startActivityForResult(intent, RC_SIGN_IN);
signIn.launch(signInIntent);
}

@OnClick(R.id.resolve_merge)
Expand DownExpand Up@@ -137,34 +142,25 @@ public void onComplete(@NonNull Task<Void> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
handleSignInResult(requestCode, resultCode, data);
}

private void handleSignInResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
private void handleSignInResult(int resultCode, @Nullable IdpResponse response) {
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
}

private void updateUI() {
Expand DownExpand Up@@ -212,4 +208,9 @@ private String getUserIdentifier(FirebaseUser user) {
return "unknown";
}
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
handleSignInResult(result.getResultCode(), result.getIdpResponse());
}
}
39 changes: 20 additions & 19 deletions app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,6 +31,8 @@
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.ui.auth.util.ExtraConstants;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
Expand All@@ -45,6 +47,8 @@
import java.util.ArrayList;
import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All@@ -56,7 +60,8 @@
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AuthUiActivity extends AppCompatActivity {
public class AuthUiActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {
private static final String TAG = "AuthUiActivity";

private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/";
Expand All@@ -66,8 +71,6 @@ public class AuthUiActivity extends AppCompatActivity {
private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google" +
".com/terms/analytics/#7_privacy";

private static final int RC_SIGN_IN = 100;

@BindView(R.id.root) View mRootView;

@BindView(R.id.google_provider) CheckBox mUseGoogleProvider;
Expand DownExpand Up@@ -111,6 +114,9 @@ public class AuthUiActivity extends AppCompatActivity {
@BindView(R.id.require_name) CheckBox mRequireName;
@BindView(R.id.use_auth_emulator) CheckBox mUseEmulator;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@NonNull
public static Intent createIntent(@NonNull Context context) {
return new Intent(context, AuthUiActivity.class);
Expand DownExpand Up@@ -237,11 +243,11 @@ public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) {

@OnClick(R.id.sign_in)
public void signIn() {
startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN);
signIn.launch(getSignInIntent(/*link=*/null));
}

public void signInWithEmailLink(@Nullable String link) {
startActivityForResult(buildSignInIntent(link), RC_SIGN_IN);
signIn.launch(getSignInIntent(link));
}

@NonNull
Expand All@@ -254,8 +260,7 @@ public AuthUI getAuthUI() {
return authUI;
}

@NonNull
public Intent buildSignInIntent(@Nullable String link) {
private Intent getSignInIntent(@Nullable String link) {
AuthUI.SignInIntentBuilder builder = getAuthUI().createSignInIntentBuilder()
.setTheme(getSelectedTheme())
.setLogo(getSelectedLogo())
Expand DownExpand Up@@ -290,7 +295,6 @@ public Intent buildSignInIntent(@Nullable String link) {
if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) {
builder.enableAnonymousUsersAutoUpgrade();
}

return builder.build();
}

Expand All@@ -309,14 +313,6 @@ public void onComplete(@NonNull Task<AuthResult> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
handleSignInResponse(resultCode, data);
}
}

@Override
protected void onResume() {
super.onResume();
Expand All@@ -327,9 +323,7 @@ protected void onResume() {
}
}

private void handleSignInResponse(int resultCode, @Nullable Intent data) {
IdpResponse response = IdpResponse.fromResultIntent(data);

private void handleSignInResponse(int resultCode, @Nullable IdpResponse response) {
// Successfully signed in
if (resultCode == RESULT_OK) {
startSignedInActivity(response);
Expand DownExpand Up@@ -529,4 +523,11 @@ private List<String> getFacebookPermissions() {
private void showSnackbar(@StringRes int errorMessageRes) {
Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG).show();
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
// Successfully signed in
IdpResponse response = result.getIdpResponse();
handleSignInResponse(result.getResultCode(), response);
}
}
4 changes: 4 additions & 0 deletions auth/build.gradle.kts
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,10 @@ android {
}

dependencies {
implementation(Config.Libs.Androidx.activity)
// The new activity result APIs force us to include Fragment 1.3.0
// See https://issuetracker.google.com/issues/152554847
implementation(Config.Libs.Androidx.fragment)
implementation(Config.Libs.Androidx.design)
implementation(Config.Libs.Androidx.customTabs)
implementation(Config.Libs.Androidx.constraint)
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
package com.firebase.ui.auth;

import android.content.Context;
import android.content.Intent;

import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;

import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* A {@link ActivityResultContract} describing that the caller can launch authentication flow with a
* {@link Intent} and is guaranteed to receive a {@link FirebaseAuthUIAuthenticationResult} as
* result. The given input intent <b>must</b> be created using a
* {@link com.firebase.ui.auth.AuthUI.SignInIntentBuilder} in order to guarantee a successful
* launch of the authentication flow.
*/
public class FirebaseAuthUIActivityResultContract extends
ActivityResultContract<Intent, FirebaseAuthUIAuthenticationResult> {

@NonNull
@Override
public Intent createIntent(@NonNull Context context, Intent input) {
return input;
}

@Override
@NonNull
public FirebaseAuthUIAuthenticationResult parseResult(int resultCode, @Nullable Intent intent) {
return new FirebaseAuthUIAuthenticationResult(resultCode, IdpResponse.fromResultIntent(intent));
}

}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
package com.firebase.ui.auth.data.model;

import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* Result of launching a {@link FirebaseAuthUIActivityResultContract}
*/
public class FirebaseAuthUIAuthenticationResult {

@Nullable
private final IdpResponse idpResponse;
@NonNull
private final Integer resultCode;

public FirebaseAuthUIAuthenticationResult(@NonNull Integer resultCode, @Nullable IdpResponse idpResponse) {
this.idpResponse = idpResponse;
this.resultCode = resultCode;
}

/**
* The contained {@link IdpResponse} returned from the Firebase library
*/
@Nullable
public IdpResponse getIdpResponse() {
return idpResponse;
}

/**
* The result code of the received activity result
*
* @see android.app.Activity.RESULT_CANCELED
* @see android.app.Activity.RESULT_OK
*/
@NonNull
public Integer getResultCode() {
return resultCode;
}

@Override
public int hashCode() {
int result = idpResponse == null ? 0 : idpResponse.hashCode();
result = 31 * result + resultCode.hashCode();
return result;
}

@Override
public String toString() {
return "FirebaseAuthUIAuthenticationResult{" +
"idpResponse=" + idpResponse +
", resultCode='" + resultCode +
'}';
}
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Config.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,9 +26,11 @@ object Config {

object Androidx {
const val annotations = "androidx.annotation:annotation:1.1.0"
const val activity = "androidx.activity:activity:1.2.0"
const val customTabs = "androidx.browser:browser:1.0.0"
const val cardView = "androidx.cardview:cardview:1.0.0"
const val constraint = "androidx.constraintlayout:constraintlayout:2.0.4"
const val fragment = "androidx.fragment:fragment:1.3.0"
const val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:2.2.0"
const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:2.2.0"
const val lifecycleRuntime = "androidx.lifecycle:lifecycle-runtime:2.2.0"
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,9 @@

import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
import com.google.android.gms.tasks.OnCompleteListener;
Expand All@@ -22,19 +24,20 @@

import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AnonymousUpgradeActivity extends AppCompatActivity {
public class AnonymousUpgradeActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {

private static final String TAG = "AccountLink";

private static final int RC_SIGN_IN = 123;

@BindView(R.id.status_text)
TextView mStatus;

Expand All@@ -52,6 +55,9 @@ public class AnonymousUpgradeActivity extends AppCompatActivity {

private AuthCredential mPendingCredential;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All@@ -64,8 +70,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Occurs after catching an email link
IdpResponse response = IdpResponse.fromResultIntent(getIntent());
if (response != null) {
handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
getIntent());
handleSignInResult(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, response);
}
}

Expand All@@ -90,12 +95,12 @@ public void onComplete(@NonNull Task<AuthResult> task) {
@OnClick(R.id.begin_flow)
public void startAuthUI() {
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
Intent signInIntent = AuthUI.getInstance().createSignInIntentBuilder()
.setLogo(R.drawable.firebase_auth_120dp)
.setAvailableProviders(providers)
.enableAnonymousUsersAutoUpgrade()
.build();
startActivityForResult(intent, RC_SIGN_IN);
signIn.launch(signInIntent);
}

@OnClick(R.id.resolve_merge)
Expand DownExpand Up@@ -137,34 +142,25 @@ public void onComplete(@NonNull Task<Void> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
handleSignInResult(requestCode, resultCode, data);
}

private void handleSignInResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
private void handleSignInResult(int resultCode, @Nullable IdpResponse response) {
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
}

private void updateUI() {
Expand DownExpand Up@@ -212,4 +208,9 @@ private String getUserIdentifier(FirebaseUser user) {
return "unknown";
}
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
handleSignInResult(result.getResultCode(), result.getIdpResponse());
}
}
39 changes: 20 additions & 19 deletions app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,6 +31,8 @@
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.ui.auth.util.ExtraConstants;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
Expand All@@ -45,6 +47,8 @@
import java.util.ArrayList;
import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All@@ -56,7 +60,8 @@
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AuthUiActivity extends AppCompatActivity {
public class AuthUiActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {
private static final String TAG = "AuthUiActivity";

private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/";
Expand All@@ -66,8 +71,6 @@ public class AuthUiActivity extends AppCompatActivity {
private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google" +
".com/terms/analytics/#7_privacy";

private static final int RC_SIGN_IN = 100;

@BindView(R.id.root) View mRootView;

@BindView(R.id.google_provider) CheckBox mUseGoogleProvider;
Expand DownExpand Up@@ -111,6 +114,9 @@ public class AuthUiActivity extends AppCompatActivity {
@BindView(R.id.require_name) CheckBox mRequireName;
@BindView(R.id.use_auth_emulator) CheckBox mUseEmulator;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@NonNull
public static Intent createIntent(@NonNull Context context) {
return new Intent(context, AuthUiActivity.class);
Expand DownExpand Up@@ -237,11 +243,11 @@ public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) {

@OnClick(R.id.sign_in)
public void signIn() {
startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN);
signIn.launch(getSignInIntent(/*link=*/null));
}

public void signInWithEmailLink(@Nullable String link) {
startActivityForResult(buildSignInIntent(link), RC_SIGN_IN);
signIn.launch(getSignInIntent(link));
}

@NonNull
Expand All@@ -254,8 +260,7 @@ public AuthUI getAuthUI() {
return authUI;
}

@NonNull
public Intent buildSignInIntent(@Nullable String link) {
private Intent getSignInIntent(@Nullable String link) {
AuthUI.SignInIntentBuilder builder = getAuthUI().createSignInIntentBuilder()
.setTheme(getSelectedTheme())
.setLogo(getSelectedLogo())
Expand DownExpand Up@@ -290,7 +295,6 @@ public Intent buildSignInIntent(@Nullable String link) {
if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) {
builder.enableAnonymousUsersAutoUpgrade();
}

return builder.build();
}

Expand All@@ -309,14 +313,6 @@ public void onComplete(@NonNull Task<AuthResult> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
handleSignInResponse(resultCode, data);
}
}

@Override
protected void onResume() {
super.onResume();
Expand All@@ -327,9 +323,7 @@ protected void onResume() {
}
}

private void handleSignInResponse(int resultCode, @Nullable Intent data) {
IdpResponse response = IdpResponse.fromResultIntent(data);

private void handleSignInResponse(int resultCode, @Nullable IdpResponse response) {
// Successfully signed in
if (resultCode == RESULT_OK) {
startSignedInActivity(response);
Expand DownExpand Up@@ -529,4 +523,11 @@ private List<String> getFacebookPermissions() {
private void showSnackbar(@StringRes int errorMessageRes) {
Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG).show();
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
// Successfully signed in
IdpResponse response = result.getIdpResponse();
handleSignInResponse(result.getResultCode(), response);
}
}
4 changes: 4 additions & 0 deletions auth/build.gradle.kts
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,10 @@ android {
}

dependencies {
implementation(Config.Libs.Androidx.activity)
// The new activity result APIs force us to include Fragment 1.3.0
// See https://issuetracker.google.com/issues/152554847
implementation(Config.Libs.Androidx.fragment)
implementation(Config.Libs.Androidx.design)
implementation(Config.Libs.Androidx.customTabs)
implementation(Config.Libs.Androidx.constraint)
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
package com.firebase.ui.auth;

import android.content.Context;
import android.content.Intent;

import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;

import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* A {@link ActivityResultContract} describing that the caller can launch authentication flow with a
* {@link Intent} and is guaranteed to receive a {@link FirebaseAuthUIAuthenticationResult} as
* result. The given input intent <b>must</b> be created using a
* {@link com.firebase.ui.auth.AuthUI.SignInIntentBuilder} in order to guarantee a successful
* launch of the authentication flow.
*/
public class FirebaseAuthUIActivityResultContract extends
ActivityResultContract<Intent, FirebaseAuthUIAuthenticationResult> {

@NonNull
@Override
public Intent createIntent(@NonNull Context context, Intent input) {
return input;
}

@Override
@NonNull
public FirebaseAuthUIAuthenticationResult parseResult(int resultCode, @Nullable Intent intent) {
return new FirebaseAuthUIAuthenticationResult(resultCode, IdpResponse.fromResultIntent(intent));
}

}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
package com.firebase.ui.auth.data.model;

import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* Result of launching a {@link FirebaseAuthUIActivityResultContract}
*/
public class FirebaseAuthUIAuthenticationResult {

@Nullable
private final IdpResponse idpResponse;
@NonNull
private final Integer resultCode;

public FirebaseAuthUIAuthenticationResult(@NonNull Integer resultCode, @Nullable IdpResponse idpResponse) {
this.idpResponse = idpResponse;
this.resultCode = resultCode;
}

/**
* The contained {@link IdpResponse} returned from the Firebase library
*/
@Nullable
public IdpResponse getIdpResponse() {
return idpResponse;
}

/**
* The result code of the received activity result
*
* @see android.app.Activity.RESULT_CANCELED
* @see android.app.Activity.RESULT_OK
*/
@NonNull
public Integer getResultCode() {
return resultCode;
}

@Override
public int hashCode() {
int result = idpResponse == null ? 0 : idpResponse.hashCode();
result = 31 * result + resultCode.hashCode();
return result;
}

@Override
public String toString() {
return "FirebaseAuthUIAuthenticationResult{" +
"idpResponse=" + idpResponse +
", resultCode='" + resultCode +
'}';
}
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Config.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,9 +26,11 @@ object Config {

object Androidx {
const val annotations = "androidx.annotation:annotation:1.1.0"
const val activity = "androidx.activity:activity:1.2.0"
const val customTabs = "androidx.browser:browser:1.0.0"
const val cardView = "androidx.cardview:cardview:1.0.0"
const val constraint = "androidx.constraintlayout:constraintlayout:2.0.4"
const val fragment = "androidx.fragment:fragment:1.3.0"
const val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:2.2.0"
const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:2.2.0"
const val lifecycleRuntime = "androidx.lifecycle:lifecycle-runtime:2.2.0"
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,9 @@

import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
import com.google.android.gms.tasks.OnCompleteListener;
Expand All@@ -22,19 +24,20 @@

import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AnonymousUpgradeActivity extends AppCompatActivity {
public class AnonymousUpgradeActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {

private static final String TAG = "AccountLink";

private static final int RC_SIGN_IN = 123;

@BindView(R.id.status_text)
TextView mStatus;

Expand All@@ -52,6 +55,9 @@ public class AnonymousUpgradeActivity extends AppCompatActivity {

private AuthCredential mPendingCredential;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All@@ -64,8 +70,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Occurs after catching an email link
IdpResponse response = IdpResponse.fromResultIntent(getIntent());
if (response != null) {
handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
getIntent());
handleSignInResult(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, response);
}
}

Expand All@@ -90,12 +95,12 @@ public void onComplete(@NonNull Task<AuthResult> task) {
@OnClick(R.id.begin_flow)
public void startAuthUI() {
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
Intent signInIntent = AuthUI.getInstance().createSignInIntentBuilder()
.setLogo(R.drawable.firebase_auth_120dp)
.setAvailableProviders(providers)
.enableAnonymousUsersAutoUpgrade()
.build();
startActivityForResult(intent, RC_SIGN_IN);
signIn.launch(signInIntent);
}

@OnClick(R.id.resolve_merge)
Expand DownExpand Up@@ -137,34 +142,25 @@ public void onComplete(@NonNull Task<Void> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
handleSignInResult(requestCode, resultCode, data);
}

private void handleSignInResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
private void handleSignInResult(int resultCode, @Nullable IdpResponse response) {
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
}

private void updateUI() {
Expand DownExpand Up@@ -212,4 +208,9 @@ private String getUserIdentifier(FirebaseUser user) {
return "unknown";
}
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
handleSignInResult(result.getResultCode(), result.getIdpResponse());
}
}
39 changes: 20 additions & 19 deletions app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,6 +31,8 @@
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.ui.auth.util.ExtraConstants;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
Expand All@@ -45,6 +47,8 @@
import java.util.ArrayList;
import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All@@ -56,7 +60,8 @@
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AuthUiActivity extends AppCompatActivity {
public class AuthUiActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {
private static final String TAG = "AuthUiActivity";

private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/";
Expand All@@ -66,8 +71,6 @@ public class AuthUiActivity extends AppCompatActivity {
private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google" +
".com/terms/analytics/#7_privacy";

private static final int RC_SIGN_IN = 100;

@BindView(R.id.root) View mRootView;

@BindView(R.id.google_provider) CheckBox mUseGoogleProvider;
Expand DownExpand Up@@ -111,6 +114,9 @@ public class AuthUiActivity extends AppCompatActivity {
@BindView(R.id.require_name) CheckBox mRequireName;
@BindView(R.id.use_auth_emulator) CheckBox mUseEmulator;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@NonNull
public static Intent createIntent(@NonNull Context context) {
return new Intent(context, AuthUiActivity.class);
Expand DownExpand Up@@ -237,11 +243,11 @@ public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) {

@OnClick(R.id.sign_in)
public void signIn() {
startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN);
signIn.launch(getSignInIntent(/*link=*/null));
}

public void signInWithEmailLink(@Nullable String link) {
startActivityForResult(buildSignInIntent(link), RC_SIGN_IN);
signIn.launch(getSignInIntent(link));
}

@NonNull
Expand All@@ -254,8 +260,7 @@ public AuthUI getAuthUI() {
return authUI;
}

@NonNull
public Intent buildSignInIntent(@Nullable String link) {
private Intent getSignInIntent(@Nullable String link) {
AuthUI.SignInIntentBuilder builder = getAuthUI().createSignInIntentBuilder()
.setTheme(getSelectedTheme())
.setLogo(getSelectedLogo())
Expand DownExpand Up@@ -290,7 +295,6 @@ public Intent buildSignInIntent(@Nullable String link) {
if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) {
builder.enableAnonymousUsersAutoUpgrade();
}

return builder.build();
}

Expand All@@ -309,14 +313,6 @@ public void onComplete(@NonNull Task<AuthResult> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
handleSignInResponse(resultCode, data);
}
}

@Override
protected void onResume() {
super.onResume();
Expand All@@ -327,9 +323,7 @@ protected void onResume() {
}
}

private void handleSignInResponse(int resultCode, @Nullable Intent data) {
IdpResponse response = IdpResponse.fromResultIntent(data);

private void handleSignInResponse(int resultCode, @Nullable IdpResponse response) {
// Successfully signed in
if (resultCode == RESULT_OK) {
startSignedInActivity(response);
Expand DownExpand Up@@ -529,4 +523,11 @@ private List<String> getFacebookPermissions() {
private void showSnackbar(@StringRes int errorMessageRes) {
Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG).show();
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
// Successfully signed in
IdpResponse response = result.getIdpResponse();
handleSignInResponse(result.getResultCode(), response);
}
}
4 changes: 4 additions & 0 deletions auth/build.gradle.kts
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,10 @@ android {
}

dependencies {
implementation(Config.Libs.Androidx.activity)
// The new activity result APIs force us to include Fragment 1.3.0
// See https://issuetracker.google.com/issues/152554847
implementation(Config.Libs.Androidx.fragment)
implementation(Config.Libs.Androidx.design)
implementation(Config.Libs.Androidx.customTabs)
implementation(Config.Libs.Androidx.constraint)
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
package com.firebase.ui.auth;

import android.content.Context;
import android.content.Intent;

import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;

import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* A {@link ActivityResultContract} describing that the caller can launch authentication flow with a
* {@link Intent} and is guaranteed to receive a {@link FirebaseAuthUIAuthenticationResult} as
* result. The given input intent <b>must</b> be created using a
* {@link com.firebase.ui.auth.AuthUI.SignInIntentBuilder} in order to guarantee a successful
* launch of the authentication flow.
*/
public class FirebaseAuthUIActivityResultContract extends
ActivityResultContract<Intent, FirebaseAuthUIAuthenticationResult> {

@NonNull
@Override
public Intent createIntent(@NonNull Context context, Intent input) {
return input;
}

@Override
@NonNull
public FirebaseAuthUIAuthenticationResult parseResult(int resultCode, @Nullable Intent intent) {
return new FirebaseAuthUIAuthenticationResult(resultCode, IdpResponse.fromResultIntent(intent));
}

}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
package com.firebase.ui.auth.data.model;

import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* Result of launching a {@link FirebaseAuthUIActivityResultContract}
*/
public class FirebaseAuthUIAuthenticationResult {

@Nullable
private final IdpResponse idpResponse;
@NonNull
private final Integer resultCode;

public FirebaseAuthUIAuthenticationResult(@NonNull Integer resultCode, @Nullable IdpResponse idpResponse) {
this.idpResponse = idpResponse;
this.resultCode = resultCode;
}

/**
* The contained {@link IdpResponse} returned from the Firebase library
*/
@Nullable
public IdpResponse getIdpResponse() {
return idpResponse;
}

/**
* The result code of the received activity result
*
* @see android.app.Activity.RESULT_CANCELED
* @see android.app.Activity.RESULT_OK
*/
@NonNull
public Integer getResultCode() {
return resultCode;
}

@Override
public int hashCode() {
int result = idpResponse == null ? 0 : idpResponse.hashCode();
result = 31 * result + resultCode.hashCode();
return result;
}

@Override
public String toString() {
return "FirebaseAuthUIAuthenticationResult{" +
"idpResponse=" + idpResponse +
", resultCode='" + resultCode +
'}';
}
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Config.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,9 +26,11 @@ object Config {

object Androidx {
const val annotations = "androidx.annotation:annotation:1.1.0"
const val activity = "androidx.activity:activity:1.2.0"
const val customTabs = "androidx.browser:browser:1.0.0"
const val cardView = "androidx.cardview:cardview:1.0.0"
const val constraint = "androidx.constraintlayout:constraintlayout:2.0.4"
const val fragment = "androidx.fragment:fragment:1.3.0"
const val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:2.2.0"
const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:2.2.0"
const val lifecycleRuntime = "androidx.lifecycle:lifecycle-runtime:2.2.0"
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,9 @@

import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
import com.google.android.gms.tasks.OnCompleteListener;
Expand All@@ -22,19 +24,20 @@

import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AnonymousUpgradeActivity extends AppCompatActivity {
public class AnonymousUpgradeActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {

private static final String TAG = "AccountLink";

private static final int RC_SIGN_IN = 123;

@BindView(R.id.status_text)
TextView mStatus;

Expand All@@ -52,6 +55,9 @@ public class AnonymousUpgradeActivity extends AppCompatActivity {

private AuthCredential mPendingCredential;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All@@ -64,8 +70,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Occurs after catching an email link
IdpResponse response = IdpResponse.fromResultIntent(getIntent());
if (response != null) {
handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
getIntent());
handleSignInResult(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, response);
}
}

Expand All@@ -90,12 +95,12 @@ public void onComplete(@NonNull Task<AuthResult> task) {
@OnClick(R.id.begin_flow)
public void startAuthUI() {
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
Intent signInIntent = AuthUI.getInstance().createSignInIntentBuilder()
.setLogo(R.drawable.firebase_auth_120dp)
.setAvailableProviders(providers)
.enableAnonymousUsersAutoUpgrade()
.build();
startActivityForResult(intent, RC_SIGN_IN);
signIn.launch(signInIntent);
}

@OnClick(R.id.resolve_merge)
Expand DownExpand Up@@ -137,34 +142,25 @@ public void onComplete(@NonNull Task<Void> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
handleSignInResult(requestCode, resultCode, data);
}

private void handleSignInResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
private void handleSignInResult(int resultCode, @Nullable IdpResponse response) {
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
}

private void updateUI() {
Expand DownExpand Up@@ -212,4 +208,9 @@ private String getUserIdentifier(FirebaseUser user) {
return "unknown";
}
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
handleSignInResult(result.getResultCode(), result.getIdpResponse());
}
}
39 changes: 20 additions & 19 deletions app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,6 +31,8 @@
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.ui.auth.util.ExtraConstants;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
Expand All@@ -45,6 +47,8 @@
import java.util.ArrayList;
import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All@@ -56,7 +60,8 @@
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AuthUiActivity extends AppCompatActivity {
public class AuthUiActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {
private static final String TAG = "AuthUiActivity";

private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/";
Expand All@@ -66,8 +71,6 @@ public class AuthUiActivity extends AppCompatActivity {
private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google" +
".com/terms/analytics/#7_privacy";

private static final int RC_SIGN_IN = 100;

@BindView(R.id.root) View mRootView;

@BindView(R.id.google_provider) CheckBox mUseGoogleProvider;
Expand DownExpand Up@@ -111,6 +114,9 @@ public class AuthUiActivity extends AppCompatActivity {
@BindView(R.id.require_name) CheckBox mRequireName;
@BindView(R.id.use_auth_emulator) CheckBox mUseEmulator;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@NonNull
public static Intent createIntent(@NonNull Context context) {
return new Intent(context, AuthUiActivity.class);
Expand DownExpand Up@@ -237,11 +243,11 @@ public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) {

@OnClick(R.id.sign_in)
public void signIn() {
startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN);
signIn.launch(getSignInIntent(/*link=*/null));
}

public void signInWithEmailLink(@Nullable String link) {
startActivityForResult(buildSignInIntent(link), RC_SIGN_IN);
signIn.launch(getSignInIntent(link));
}

@NonNull
Expand All@@ -254,8 +260,7 @@ public AuthUI getAuthUI() {
return authUI;
}

@NonNull
public Intent buildSignInIntent(@Nullable String link) {
private Intent getSignInIntent(@Nullable String link) {
AuthUI.SignInIntentBuilder builder = getAuthUI().createSignInIntentBuilder()
.setTheme(getSelectedTheme())
.setLogo(getSelectedLogo())
Expand DownExpand Up@@ -290,7 +295,6 @@ public Intent buildSignInIntent(@Nullable String link) {
if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) {
builder.enableAnonymousUsersAutoUpgrade();
}

return builder.build();
}

Expand All@@ -309,14 +313,6 @@ public void onComplete(@NonNull Task<AuthResult> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
handleSignInResponse(resultCode, data);
}
}

@Override
protected void onResume() {
super.onResume();
Expand All@@ -327,9 +323,7 @@ protected void onResume() {
}
}

private void handleSignInResponse(int resultCode, @Nullable Intent data) {
IdpResponse response = IdpResponse.fromResultIntent(data);

private void handleSignInResponse(int resultCode, @Nullable IdpResponse response) {
// Successfully signed in
if (resultCode == RESULT_OK) {
startSignedInActivity(response);
Expand DownExpand Up@@ -529,4 +523,11 @@ private List<String> getFacebookPermissions() {
private void showSnackbar(@StringRes int errorMessageRes) {
Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG).show();
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
// Successfully signed in
IdpResponse response = result.getIdpResponse();
handleSignInResponse(result.getResultCode(), response);
}
}
4 changes: 4 additions & 0 deletions auth/build.gradle.kts
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,10 @@ android {
}

dependencies {
implementation(Config.Libs.Androidx.activity)
// The new activity result APIs force us to include Fragment 1.3.0
// See https://issuetracker.google.com/issues/152554847
implementation(Config.Libs.Androidx.fragment)
implementation(Config.Libs.Androidx.design)
implementation(Config.Libs.Androidx.customTabs)
implementation(Config.Libs.Androidx.constraint)
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
package com.firebase.ui.auth;

import android.content.Context;
import android.content.Intent;

import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;

import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* A {@link ActivityResultContract} describing that the caller can launch authentication flow with a
* {@link Intent} and is guaranteed to receive a {@link FirebaseAuthUIAuthenticationResult} as
* result. The given input intent <b>must</b> be created using a
* {@link com.firebase.ui.auth.AuthUI.SignInIntentBuilder} in order to guarantee a successful
* launch of the authentication flow.
*/
public class FirebaseAuthUIActivityResultContract extends
ActivityResultContract<Intent, FirebaseAuthUIAuthenticationResult> {

@NonNull
@Override
public Intent createIntent(@NonNull Context context, Intent input) {
return input;
}

@Override
@NonNull
public FirebaseAuthUIAuthenticationResult parseResult(int resultCode, @Nullable Intent intent) {
return new FirebaseAuthUIAuthenticationResult(resultCode, IdpResponse.fromResultIntent(intent));
}

}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
package com.firebase.ui.auth.data.model;

import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* Result of launching a {@link FirebaseAuthUIActivityResultContract}
*/
public class FirebaseAuthUIAuthenticationResult {

@Nullable
private final IdpResponse idpResponse;
@NonNull
private final Integer resultCode;

public FirebaseAuthUIAuthenticationResult(@NonNull Integer resultCode, @Nullable IdpResponse idpResponse) {
this.idpResponse = idpResponse;
this.resultCode = resultCode;
}

/**
* The contained {@link IdpResponse} returned from the Firebase library
*/
@Nullable
public IdpResponse getIdpResponse() {
return idpResponse;
}

/**
* The result code of the received activity result
*
* @see android.app.Activity.RESULT_CANCELED
* @see android.app.Activity.RESULT_OK
*/
@NonNull
public Integer getResultCode() {
return resultCode;
}

@Override
public int hashCode() {
int result = idpResponse == null ? 0 : idpResponse.hashCode();
result = 31 * result + resultCode.hashCode();
return result;
}

@Override
public String toString() {
return "FirebaseAuthUIAuthenticationResult{" +
"idpResponse=" + idpResponse +
", resultCode='" + resultCode +
'}';
}
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Config.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,9 +26,11 @@ object Config {

object Androidx {
const val annotations = "androidx.annotation:annotation:1.1.0"
const val activity = "androidx.activity:activity:1.2.0"
const val customTabs = "androidx.browser:browser:1.0.0"
const val cardView = "androidx.cardview:cardview:1.0.0"
const val constraint = "androidx.constraintlayout:constraintlayout:2.0.4"
const val fragment = "androidx.fragment:fragment:1.3.0"
const val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:2.2.0"
const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:2.2.0"
const val lifecycleRuntime = "androidx.lifecycle:lifecycle-runtime:2.2.0"
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,7 +10,9 @@

import com.firebase.ui.auth.AuthUI;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
import com.google.android.gms.tasks.OnCompleteListener;
Expand All@@ -22,19 +24,20 @@

import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AnonymousUpgradeActivity extends AppCompatActivity {
public class AnonymousUpgradeActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {

private static final String TAG = "AccountLink";

private static final int RC_SIGN_IN = 123;

@BindView(R.id.status_text)
TextView mStatus;

Expand All@@ -52,6 +55,9 @@ public class AnonymousUpgradeActivity extends AppCompatActivity {

private AuthCredential mPendingCredential;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Expand All@@ -64,8 +70,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
// Occurs after catching an email link
IdpResponse response = IdpResponse.fromResultIntent(getIntent());
if (response != null) {
handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT,
getIntent());
handleSignInResult(ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, response);
}
}

Expand All@@ -90,12 +95,12 @@ public void onComplete(@NonNull Task<AuthResult> task) {
@OnClick(R.id.begin_flow)
public void startAuthUI() {
List<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this);
Intent intent = AuthUI.getInstance().createSignInIntentBuilder()
Intent signInIntent = AuthUI.getInstance().createSignInIntentBuilder()
.setLogo(R.drawable.firebase_auth_120dp)
.setAvailableProviders(providers)
.enableAnonymousUsersAutoUpgrade()
.build();
startActivityForResult(intent, RC_SIGN_IN);
signIn.launch(signInIntent);
}

@OnClick(R.id.resolve_merge)
Expand DownExpand Up@@ -137,34 +142,25 @@ public void onComplete(@NonNull Task<Void> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
handleSignInResult(requestCode, resultCode, data);
}

private void handleSignInResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
IdpResponse response = IdpResponse.fromResultIntent(data);
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
private void handleSignInResult(int resultCode, @Nullable IdpResponse response) {
if (response == null) {
// User pressed back button
return;
}
if (resultCode == RESULT_OK) {
setStatus("Signed in as " + getUserIdentifier(FirebaseAuth.getInstance()
.getCurrentUser()));
} else if (response.getError().getErrorCode() == ErrorCodes
.ANONYMOUS_UPGRADE_MERGE_CONFLICT) {
setStatus("Merge conflict: user already exists.");
mResolveMergeButton.setEnabled(true);
mPendingCredential = response.getCredentialForLinking();
} else {
Toast.makeText(this, "Auth error, see logs", Toast.LENGTH_SHORT).show();
Log.w(TAG, "Error: " + response.getError().getMessage(), response.getError());
}

updateUI();
}

private void updateUI() {
Expand DownExpand Up@@ -212,4 +208,9 @@ private String getUserIdentifier(FirebaseUser user) {
return "unknown";
}
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
handleSignInResult(result.getResultCode(), result.getIdpResponse());
}
}
39 changes: 20 additions & 19 deletions app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java
Original file line numberDiff line numberDiff line change
Expand Up@@ -31,6 +31,8 @@
import com.firebase.ui.auth.AuthUI.IdpConfig;
import com.firebase.ui.auth.ErrorCodes;
import com.firebase.ui.auth.IdpResponse;
import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;
import com.firebase.ui.auth.util.ExtraConstants;
import com.firebase.uidemo.R;
import com.firebase.uidemo.util.ConfigurationUtils;
Expand All@@ -45,6 +47,8 @@
import java.util.ArrayList;
import java.util.List;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
Expand All@@ -56,7 +60,8 @@
import butterknife.ButterKnife;
import butterknife.OnClick;

public class AuthUiActivity extends AppCompatActivity {
public class AuthUiActivity extends AppCompatActivity
implements ActivityResultCallback<FirebaseAuthUIAuthenticationResult> {
private static final String TAG = "AuthUiActivity";

private static final String GOOGLE_TOS_URL = "https://www.google.com/policies/terms/";
Expand All@@ -66,8 +71,6 @@ public class AuthUiActivity extends AppCompatActivity {
private static final String FIREBASE_PRIVACY_POLICY_URL = "https://firebase.google" +
".com/terms/analytics/#7_privacy";

private static final int RC_SIGN_IN = 100;

@BindView(R.id.root) View mRootView;

@BindView(R.id.google_provider) CheckBox mUseGoogleProvider;
Expand DownExpand Up@@ -111,6 +114,9 @@ public class AuthUiActivity extends AppCompatActivity {
@BindView(R.id.require_name) CheckBox mRequireName;
@BindView(R.id.use_auth_emulator) CheckBox mUseEmulator;

private final ActivityResultLauncher<Intent> signIn =
registerForActivityResult(new FirebaseAuthUIActivityResultContract(), this);

@NonNull
public static Intent createIntent(@NonNull Context context) {
return new Intent(context, AuthUiActivity.class);
Expand DownExpand Up@@ -237,11 +243,11 @@ public void flipEmailLinkProviderCheckbox(boolean passwordProviderIsChecked) {

@OnClick(R.id.sign_in)
public void signIn() {
startActivityForResult(buildSignInIntent(/*link=*/null), RC_SIGN_IN);
signIn.launch(getSignInIntent(/*link=*/null));
}

public void signInWithEmailLink(@Nullable String link) {
startActivityForResult(buildSignInIntent(link), RC_SIGN_IN);
signIn.launch(getSignInIntent(link));
}

@NonNull
Expand All@@ -254,8 +260,7 @@ public AuthUI getAuthUI() {
return authUI;
}

@NonNull
public Intent buildSignInIntent(@Nullable String link) {
private Intent getSignInIntent(@Nullable String link) {
AuthUI.SignInIntentBuilder builder = getAuthUI().createSignInIntentBuilder()
.setTheme(getSelectedTheme())
.setLogo(getSelectedLogo())
Expand DownExpand Up@@ -290,7 +295,6 @@ public Intent buildSignInIntent(@Nullable String link) {
if (auth.getCurrentUser() != null && auth.getCurrentUser().isAnonymous()) {
builder.enableAnonymousUsersAutoUpgrade();
}

return builder.build();
}

Expand All@@ -309,14 +313,6 @@ public void onComplete(@NonNull Task<AuthResult> task) {
});
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RC_SIGN_IN) {
handleSignInResponse(resultCode, data);
}
}

@Override
protected void onResume() {
super.onResume();
Expand All@@ -327,9 +323,7 @@ protected void onResume() {
}
}

private void handleSignInResponse(int resultCode, @Nullable Intent data) {
IdpResponse response = IdpResponse.fromResultIntent(data);

private void handleSignInResponse(int resultCode, @Nullable IdpResponse response) {
// Successfully signed in
if (resultCode == RESULT_OK) {
startSignedInActivity(response);
Expand DownExpand Up@@ -529,4 +523,11 @@ private List<String> getFacebookPermissions() {
private void showSnackbar(@StringRes int errorMessageRes) {
Snackbar.make(mRootView, errorMessageRes, Snackbar.LENGTH_LONG).show();
}

@Override
public void onActivityResult(@NonNull FirebaseAuthUIAuthenticationResult result) {
// Successfully signed in
IdpResponse response = result.getIdpResponse();
handleSignInResponse(result.getResultCode(), response);
}
}
4 changes: 4 additions & 0 deletions auth/build.gradle.kts
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,10 @@ android {
}

dependencies {
implementation(Config.Libs.Androidx.activity)
// The new activity result APIs force us to include Fragment 1.3.0
// See https://issuetracker.google.com/issues/152554847
implementation(Config.Libs.Androidx.fragment)
implementation(Config.Libs.Androidx.design)
implementation(Config.Libs.Androidx.customTabs)
implementation(Config.Libs.Androidx.constraint)
Expand Down
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
package com.firebase.ui.auth;

import android.content.Context;
import android.content.Intent;

import com.firebase.ui.auth.data.model.FirebaseAuthUIAuthenticationResult;

import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* A {@link ActivityResultContract} describing that the caller can launch authentication flow with a
* {@link Intent} and is guaranteed to receive a {@link FirebaseAuthUIAuthenticationResult} as
* result. The given input intent <b>must</b> be created using a
* {@link com.firebase.ui.auth.AuthUI.SignInIntentBuilder} in order to guarantee a successful
* launch of the authentication flow.
*/
public class FirebaseAuthUIActivityResultContract extends
ActivityResultContract<Intent, FirebaseAuthUIAuthenticationResult> {

@NonNull
@Override
public Intent createIntent(@NonNull Context context, Intent input) {
return input;
}

@Override
@NonNull
public FirebaseAuthUIAuthenticationResult parseResult(int resultCode, @Nullable Intent intent) {
return new FirebaseAuthUIAuthenticationResult(resultCode, IdpResponse.fromResultIntent(intent));
}

}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
package com.firebase.ui.auth.data.model;

import com.firebase.ui.auth.FirebaseAuthUIActivityResultContract;
import com.firebase.ui.auth.IdpResponse;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
* Result of launching a {@link FirebaseAuthUIActivityResultContract}
*/
public class FirebaseAuthUIAuthenticationResult {

@Nullable
private final IdpResponse idpResponse;
@NonNull
private final Integer resultCode;

public FirebaseAuthUIAuthenticationResult(@NonNull Integer resultCode, @Nullable IdpResponse idpResponse) {
this.idpResponse = idpResponse;
this.resultCode = resultCode;
}

/**
* The contained {@link IdpResponse} returned from the Firebase library
*/
@Nullable
public IdpResponse getIdpResponse() {
return idpResponse;
}

/**
* The result code of the received activity result
*
* @see android.app.Activity.RESULT_CANCELED
* @see android.app.Activity.RESULT_OK
*/
@NonNull
public Integer getResultCode() {
return resultCode;
}

@Override
public int hashCode() {
int result = idpResponse == null ? 0 : idpResponse.hashCode();
result = 31 * result + resultCode.hashCode();
return result;
}

@Override
public String toString() {
return "FirebaseAuthUIAuthenticationResult{" +
"idpResponse=" + idpResponse +
", resultCode='" + resultCode +
'}';
}
}
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Config.kt
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,9 +26,11 @@ object Config {

object Androidx {
const val annotations = "androidx.annotation:annotation:1.1.0"
const val activity = "androidx.activity:activity:1.2.0"
const val customTabs = "androidx.browser:browser:1.0.0"
const val cardView = "androidx.cardview:cardview:1.0.0"
const val constraint = "androidx.constraintlayout:constraintlayout:2.0.4"
const val fragment = "androidx.fragment:fragment:1.3.0"
const val lifecycleCompiler = "androidx.lifecycle:lifecycle-compiler:2.2.0"
const val lifecycleExtensions = "androidx.lifecycle:lifecycle-extensions:2.2.0"
const val lifecycleRuntime = "androidx.lifecycle:lifecycle-runtime:2.2.0"
Expand Down