package com.firebase.uidemo.auth; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.firebase.ui.auth.AuthUI; 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.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.auth.AuthCredential; import com.google.firebase.auth.AuthResult; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.auth.FirebaseUser; import java.util.List; 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 { private static final String TAG = "AccountLink"; private static final int RC_SIGN_IN = 123; @BindView(R.id.status_text) TextView mStatus; @BindView(R.id.anon_sign_in) Button mAnonSignInButton; @BindView(R.id.begin_flow) Button mLaunchUIButton; @BindView(R.id.resolve_merge) Button mResolveMergeButton; @BindView(R.id.sign_out) Button mSignOutButton; private AuthCredential mPendingCredential; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_anonymous_upgrade); ButterKnife.bind(this); updateUI(); // Got here from AuthUIActivity, and we need to deal with a merge conflict // Occurs after catching an email link IdpResponse response = IdpResponse.fromResultIntent(getIntent()); if (response != null) { handleSignInResult(RC_SIGN_IN, ErrorCodes.ANONYMOUS_UPGRADE_MERGE_CONFLICT, getIntent()); } } @OnClick(R.id.anon_sign_in) public void signInAnonymously() { FirebaseAuth.getInstance().signInAnonymously() .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> 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<AuthUI.IdpConfig> providers = ConfigurationUtils.getConfiguredProviders(this); Intent intent = AuthUI.getInstance().createSignInIntentBuilder() .setLogo(R.drawable.firebase_auth_120dp) .setAvailableProviders(providers) .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<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> 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<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { setStatus(null); updateUI(); } }); } @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 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"; } } }