简体   繁体   中英

Android Firebase Authentication - How to Link Existing User Account to Anonymous Account

I am having some trouble understanding how to link an existing email account to an anonymous firebase account. is this possible ? or does it only link if the email account is new ?

when i call the following code to link accounts both the anonymous account and existing account exist. but if its a new email account then i see that the new email account as the same uid as the anonymous account and the anonymous account is gone.

mAuth.getCurrentUser().linkWithCredential(credential)
        .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
            @Override
            public void onComplete(@NonNull Task<AuthResult> task) {
                if (task.isSuccessful()) {
                    Log.d(TAG, "linkWithCredential:success");
                    FirebaseUser user = task.getResult().getUser();
                    updateUI(user);
                } else {
                    Log.w(TAG, "linkWithCredential:failure", task.getException());
                    Toast.makeText(AnonymousAuthActivity.this, "Authentication failed.",
                            Toast.LENGTH_SHORT).show();
                    updateUI(null);
                }

                // ...
            }
        });

so my question is: am i able to link anonymous user account to EXISTING user account ? because then my firebase console is going to be filled with anonymous user entries.

UPDATE: Using the firebase mergService here how can i delete the anonymous account ? i dont see it returning a credential for me to delete.

the mergeService describe looks like this:

public class MyManualMergeService extends ManualMergeService {
private Iterable<DataSnapshot> mChatKeys;

@Override
public Task<Void> onLoadData() {
    final TaskCompletionSource<Void> loadTask = new TaskCompletionSource<>();
    FirebaseDatabase.getInstance()
            .getReference()
            .child("chatIndices")
            .child(FirebaseAuth.getInstance().getCurrentUser().getUid())
            .addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot snapshot) {
                    mChatKeys = snapshot.getChildren();
                    loadTask.setResult(null);
                }

                @Override
                public void onCancelled(DatabaseError error) {
                    FirebaseCrash.report(error.toException());
                }
            });
    return loadTask.getTask();
}

@Override
public Task<Void> onTransferData(IdpResponse response) {
    String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
    DatabaseReference chatIndices = FirebaseDatabase.getInstance()
            .getReference()
            .child("chatIndices")
            .child(uid);
    for (DataSnapshot snapshot : mChatKeys) {
        chatIndices.child(snapshot.getKey()).setValue(true);
        DatabaseReference chat = FirebaseDatabase.getInstance()
                .getReference()
                .child("chats")
                .child(snapshot.getKey());
        chat.child("uid").setValue(uid);
        chat.child("name").setValue("User " + uid.substring(0, 6));
    }
    return null;
}

}

this gets called after user transitions from anonymous user to a real account. how can i then know the credential so i can delete the anonymous account ?

You can't link an existing credential to anonymous user. You have to basically copy the data of the anonymous user to the existing credential user and then delete the anonymous user.

It is not possible for Firebase to handle this for you. You have 2 users with different uids and data saved on each users, not to mention different profile data on each. Firebase doesn't know which user to keep and how to merge the profile/data. In some cases, data could be saved outside of Firebase services.

FirebaseUI is currently doing a similar mechanism for upgrading anonymous users on sign in. If the credential is new, then linking will succeed without any additional action. If the credential already exists, linking will fail and the developer is expected to handle the merge conflict, copy the data from the non anonymous user and delete the anonymous user after.

This is the web flow in FirebaseUI-web: https://github.com/firebase/firebaseui-web#upgrading-anonymous-users

This is being implemented for FirebaseUI-android: https://github.com/firebase/FirebaseUI-Android/pull/1185

Here is an example with web, given an authCredential and an anonymous user signed in.

Here is a simple web example how to handle merge conflicts.

let data;
// Default App with anonymous user.
const app = firebase.app();
// Anonymous user.
anonymousUser = app.auth().currentUser;
// Get anonymous user data.
app.database().ref('users/' + app.auth().currentUser.uid)
  .once('value')
  .then(snapshot => {
    // Store anonymous user data.
    data = snapshot.val();
    // Sign in credential user.
    return app.auth().signInWithCredential(authCredential);
  })
  .then(user => {
    // Save the anonymous user's data to the credential user.
    return app.database().ref('users/' + user.uid).set(data);
  })
  .then(() => {
    // Delete anonymnous user.
    return anonymousUser.delete();
  })
})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM