diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0a381a18c..0a6d84862 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -37,6 +37,9 @@ + { private static final Class[] CLASSES = new Class[]{ AuthUiActivity.class, + AnonymousUpgradeActivity.class, FirestoreChatActivity.class, FirestorePagingActivity.class, RealtimeDbChatActivity.class, @@ -61,6 +63,7 @@ private static class ActivityChooserAdapter extends RecyclerView.Adapter() { + @Override + public void onComplete(@NonNull Task task) { + updateUI(); + + if (task.isSuccessful()) { + setStatus("Signed in anonymously as user " + + getUserIdentifier(task.getResult().getUser())); + } else { + setStatus("Anonymous sign in failed."); + } + } + }); + } + + @OnClick(R.id.begin_flow) + public void startAuthUI() { + List providers = ConfigurationUtils.getConfiguredProviders(this); + Intent intent = AuthUI.getInstance().createSignInIntentBuilder() + .setLogo(R.drawable.firebase_auth_120dp) + .setAvailableProviders(providers) + .setIsSmartLockEnabled(false) + .enableAnonymousUsersAutoUpgrade() + .build(); + startActivityForResult(intent, RC_SIGN_IN); + } + + @OnClick(R.id.resolve_merge) + public void resolveMerge() { + if (mPendingCredential == null) { + Toast.makeText(this, "Nothing to resolve.", Toast.LENGTH_SHORT).show(); + return; + } + + // TODO: Show how to do good data moving + + FirebaseAuth.getInstance().signInWithCredential(mPendingCredential) + .addOnCompleteListener(this, new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + mPendingCredential = null; + updateUI(); + + if (task.isSuccessful()) { + setStatus("Signed in as " + getUserIdentifier(task.getResult().getUser())); + } else { + Log.w(TAG, "Merge failed", task.getException()); + setStatus("Failed to resolve merge conflict, see logs."); + } + } + }); + } + + @OnClick(R.id.sign_out) + public void signOut() { + AuthUI.getInstance().signOut(this) + .addOnCompleteListener(new OnCompleteListener() { + @Override + public void onComplete(@NonNull Task task) { + setStatus(null); + updateUI(); + } + }); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, 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(); + } + } + + updateUI(); + } + } + + private void updateUI() { + FirebaseUser currentUser = FirebaseAuth.getInstance().getCurrentUser(); + + if (currentUser == null) { + // Not signed in + mAnonSignInButton.setEnabled(true); + mLaunchUIButton.setEnabled(false); + mResolveMergeButton.setEnabled(false); + mSignOutButton.setEnabled(false); + } else if (mPendingCredential == null && currentUser.isAnonymous()) { + // Anonymous user, waiting for linking + mAnonSignInButton.setEnabled(false); + mLaunchUIButton.setEnabled(true); + mResolveMergeButton.setEnabled(false); + mSignOutButton.setEnabled(true); + } else if (mPendingCredential == null && !currentUser.isAnonymous()) { + // Fully signed in + mAnonSignInButton.setEnabled(false); + mLaunchUIButton.setEnabled(false); + mResolveMergeButton.setEnabled(false); + mSignOutButton.setEnabled(true); + } else if (mPendingCredential != null) { + // Signed in anonymous, awaiting merge conflict + mAnonSignInButton.setEnabled(false); + mLaunchUIButton.setEnabled(false); + mResolveMergeButton.setEnabled(true); + mSignOutButton.setEnabled(true); + } + } + + private void setStatus(String message) { + mStatus.setText(message); + } + + private String getUserIdentifier(FirebaseUser user) { + if (user.isAnonymous()) { + return user.getUid(); + } else if (!TextUtils.isEmpty(user.getEmail())) { + return user.getEmail(); + } else if (!TextUtils.isEmpty(user.getPhoneNumber())) { + return user.getPhoneNumber(); + } else { + return "unknown"; + } + } +} diff --git a/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java b/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java index 11afcf573..c1aeb0632 100644 --- a/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java +++ b/app/src/main/java/com/firebase/uidemo/auth/AuthUiActivity.java @@ -38,6 +38,7 @@ import com.firebase.ui.auth.ErrorCodes; import com.firebase.ui.auth.IdpResponse; import com.firebase.uidemo.R; +import com.firebase.uidemo.util.ConfigurationUtils; import com.google.android.gms.common.Scopes; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; @@ -45,7 +46,6 @@ import com.google.firebase.auth.FirebaseAuth; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import butterknife.BindView; @@ -113,7 +113,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { setContentView(R.layout.auth_ui_layout); ButterKnife.bind(this); - if (isGoogleMisconfigured()) { + if (ConfigurationUtils.isGoogleMisconfigured(this)) { mUseGoogleProvider.setChecked(false); mUseGoogleProvider.setEnabled(false); mUseGoogleProvider.setText(R.string.google_label_missing_config); @@ -128,7 +128,7 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { }); } - if (isFacebookMisconfigured()) { + if (ConfigurationUtils.isFacebookMisconfigured(this)) { mUseFacebookProvider.setChecked(false); mUseFacebookProvider.setEnabled(false); mUseFacebookProvider.setText(R.string.facebook_label_missing_config); @@ -143,13 +143,13 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { }); } - if (isTwitterMisconfigured()) { + if (ConfigurationUtils.isTwitterMisconfigured(this)) { mUseTwitterProvider.setChecked(false); mUseTwitterProvider.setEnabled(false); mUseTwitterProvider.setText(R.string.twitter_label_missing_config); } - if (isGitHubMisconfigured()) { + if (ConfigurationUtils.isGitHubMisconfigured(this)) { mUseGitHubProvider.setChecked(false); mUseGitHubProvider.setEnabled(false); mUseGitHubProvider.setText(R.string.github_label_missing_config); @@ -164,8 +164,10 @@ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { }); } - if (isGoogleMisconfigured() || isFacebookMisconfigured() - || isTwitterMisconfigured() || isGitHubMisconfigured()) { + if (ConfigurationUtils.isGoogleMisconfigured(this) + || ConfigurationUtils.isFacebookMisconfigured(this) + || ConfigurationUtils.isTwitterMisconfigured(this) + || ConfigurationUtils.isGitHubMisconfigured(this)) { showSnackbar(R.string.configuration_required); } @@ -223,7 +225,7 @@ protected void onResume() { } private void handleSignInResponse(int resultCode, Intent data) { - IdpResponse response = IdpResponse.fromResultIntent(data); + final IdpResponse response = IdpResponse.fromResultIntent(data); // Successfully signed in if (resultCode == RESULT_OK) { @@ -336,33 +338,6 @@ private String getSelectedPrivacyPolicyUrl() { return FIREBASE_PRIVACY_POLICY_URL; } - private boolean isGoogleMisconfigured() { - return AuthUI.UNCONFIGURED_CONFIG_VALUE.equals(getString(R.string.default_web_client_id)); - } - - private boolean isFacebookMisconfigured() { - return AuthUI.UNCONFIGURED_CONFIG_VALUE.equals(getString(R.string.facebook_application_id)); - } - - private boolean isTwitterMisconfigured() { - List twitterConfigs = Arrays.asList( - getString(R.string.twitter_consumer_key), - getString(R.string.twitter_consumer_secret) - ); - - return twitterConfigs.contains(AuthUI.UNCONFIGURED_CONFIG_VALUE); - } - - private boolean isGitHubMisconfigured() { - List gitHubConfigs = Arrays.asList( - getString(R.string.firebase_web_host), - getString(R.string.github_client_id), - getString(R.string.github_client_secret) - ); - - return gitHubConfigs.contains(AuthUI.UNCONFIGURED_CONFIG_VALUE); - } - private void setGoogleScopesEnabled(boolean enabled) { mGoogleScopesHeader.setEnabled(enabled); mGoogleScopeDriveFile.setEnabled(enabled); diff --git a/app/src/main/java/com/firebase/uidemo/util/ConfigurationUtils.java b/app/src/main/java/com/firebase/uidemo/util/ConfigurationUtils.java new file mode 100644 index 000000000..18f3f7d0b --- /dev/null +++ b/app/src/main/java/com/firebase/uidemo/util/ConfigurationUtils.java @@ -0,0 +1,68 @@ +package com.firebase.uidemo.util; + + +import android.content.Context; +import android.content.res.Resources; + +import com.firebase.ui.auth.AuthUI; +import com.firebase.uidemo.R; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ConfigurationUtils { + + public static boolean isGoogleMisconfigured(Context context) { + return AuthUI.UNCONFIGURED_CONFIG_VALUE.equals( + context.getString(R.string.default_web_client_id)); + } + + public static boolean isFacebookMisconfigured(Context context) { + return AuthUI.UNCONFIGURED_CONFIG_VALUE.equals( + context.getString(R.string.facebook_application_id)); + } + + public static boolean isTwitterMisconfigured(Context context) { + List twitterConfigs = Arrays.asList( + context.getString(R.string.twitter_consumer_key), + context.getString(R.string.twitter_consumer_secret) + ); + + return twitterConfigs.contains(AuthUI.UNCONFIGURED_CONFIG_VALUE); + } + + public static boolean isGitHubMisconfigured(Context context) { + List gitHubConfigs = Arrays.asList( + context.getString(R.string.firebase_web_host), + context.getString(R.string.github_client_id), + context.getString(R.string.github_client_secret) + ); + + return gitHubConfigs.contains(AuthUI.UNCONFIGURED_CONFIG_VALUE); + } + + public static List getConfiguredProviders(Context context) { + List providers = new ArrayList<>(); + providers.add(new AuthUI.IdpConfig.EmailBuilder().build()); + providers.add(new AuthUI.IdpConfig.PhoneBuilder().build()); + + if (!isGoogleMisconfigured(context)) { + providers.add(new AuthUI.IdpConfig.GoogleBuilder().build()); + } + + if (!isFacebookMisconfigured(context)) { + providers.add(new AuthUI.IdpConfig.FacebookBuilder().build()); + } + + if (!isTwitterMisconfigured(context)) { + providers.add(new AuthUI.IdpConfig.TwitterBuilder().build()); + } + + if (!isGitHubMisconfigured(context)) { + providers.add(new AuthUI.IdpConfig.GitHubBuilder().build()); + } + + return providers; + } +} diff --git a/app/src/main/res/layout/activity_anonymous_upgrade.xml b/app/src/main/res/layout/activity_anonymous_upgrade.xml new file mode 100644 index 000000000..6ac9537e0 --- /dev/null +++ b/app/src/main/res/layout/activity_anonymous_upgrade.xml @@ -0,0 +1,67 @@ + + + + + + + +