Open initfusion opened 5 years ago
Hi @initfusion, you can start from this doc, which introduces how to link multiple auth providers to one account in Unity. You can also find related docs for other platforms under iOS / Android / Web and C++.
Hope this helps.
Hi @cynthiajoan, this doc is not enough for solving conflicts. Because the credentials which I linking is having an existing account so we have to delete the new account first. After that, we can link.
I have followed the doc https://firebase.google.com/docs/auth/web/account-linking
// Get reference to the currently signed-in user
var prevUser = auth.currentUser;
// Sign in user with another account
auth.signInWithCredential(credential).then(function(user) {
console.log("Sign In Success", user);
var currentUser = user;
// Merge prevUser and currentUser data stored in Firebase.
// Note: How you handle this is specific to your application
// After data is migrated delete the duplicate user
return user.delete().then(function() {
// Link the OAuth Credential to original account
return prevUser.linkWithCredential(credential);
}).then(function() {
// Sign in with the newly linked credential
return auth.signInWithCredential(credential);
});
}).catch(function(error) {
console.log("Sign In Error", error);
});
But the above code is in javascript.
In c# how to store prevUser? when I have signInWithCredantial I am lost the current user.
Hi @initfusion, if I understand correctly, in Unity/C#, we have this example maybe can solve your problem: Unity account linking
// Gather data for the currently signed in User. string currentUserId = auth.CurrentUser.UserId; string currentEmail = auth.CurrentUser.Email; string currentDisplayName = auth.CurrentUser.DisplayName; System.Uri currentPhotoUrl = auth.CurrentUser.PhotoUrl;
// Sign in with the new credentials. auth.SignInWithCredentialAsync(credential).ContinueWith(task => { if (task.IsCanceled) { Debug.LogError("SignInWithCredentialAsync was canceled."); return; } if (task.IsFaulted) { Debug.LogError("SignInWithCredentialAsync encountered an error: " + task.Exception); return; }
Firebase.Auth.FirebaseUser newUser = task.Result; Debug.LogFormat("User signed in successfully: {0} ({1})", newUser.DisplayName, newUser.UserId);
// TODO: Merge app specific details using the newUser and values from the // previous user, saved above. });
You can grab prevUser by auth.CurrentUser before signInWithCredantial.
Let me know if that works for you.
Hi @cynthiajoan Yes, I have done that way but after doing signInWithCredantial the prevUser which I have grabbed previously is also changed to the new user.
I think its sync new user to all its existing user instances.
Hi This is I am trying
var credential = EmailAuthProvider.GetCredential(email, password);
auth.CurrentUser.LinkWithCredentialAsync(credential).ContinueWithOnMainThread(task =>
{
if (task.IsCanceled)
{
Debug.Log("Cancel");
}
if (task.IsFaulted)
{
Debug.Log("Faulted");
var currentUser = auth.CurrentUser;
otherAuth.SignInWithCredentialAsync(credential).ContinueWithOnMainThread(linkTask =>
{
Debug.Log("Current: " + currentUser.UserId);
Debug.Log("New: " + linkTask.Result.UserId);
// Here both current and new have the same user.
});
}
if (task.IsCompleted)
{
Debug.Log("Completed");
}
});
HI @initfusion ,
as per @cynthiajoan suggestion, have you tried caching the individual fields you need before executing the SignInWithCredentialAsync
? The JavaScript and Unity APIs will be slightly different.
--Patrick
Hi @patm1987,
Yes, I can cache the individual fields but I need the previous user to link the user. Without a previous user, I can't call the LinkWithCredantials.
With the Unity API, you just need the credential of the account you want to link with the current one (ie: if your continuation from LinkWithCredentialAsync
succeeds, you should have linked accounts). You can get more information here:
https://firebase.google.com/docs/reference/unity/class/firebase/auth/firebase-user#linkandretrievedatawithcredentialasync
Let me know if it's not the case, but you should be able to verify that the merger worked in your firebase authentication dashboard (in console.firebase.google.com).
Hi @patm1987
Yes, it's not the case, Link account is working properly when there is no error when link. But if there is an error (ie: if the credential which is I am going to merge is already having an account).
In that case, I have to delete the existing account. for delete existing account I have to SignIn so I can get the user and using that user I can delete.
if there is another way to solve merge conflicts then let me know.
Let me know if you still not understand my problem.
@initfusion it looks like you've found a problem with both the C++ and Unity SDKs here. You're right that it's not currently possible to copy the FirebaseUser object in the C# API which is an issue in the case you've described where you want to:
However, I think it's possible to do this with multiple FirebaseApp objects instead:
otherAuth
)FirebaseAuth.DefaultInstance.CurrentUser
, sign-in to otherAuth
with the credentialsotherAuth.CurrentUser
FirebaseAuth.DefaultInstance.CurrentUser
againHi @stewartmiles
Thanks for understanding my problem. I was also tried with multiple Firebase objects but still not able to get or cache the current user's auth token.
Here is my code
otherAuth = FirebaseAuth.GetAuth(FirebaseApp.Create(AppOptions.LoadFromJsonConfig(conf.text)));
Now I am trying this but still, both are the same.
var credential = EmailAuthProvider.GetCredential(email, password);
auth.CurrentUser.LinkAndRetrieveDataWithCredentialAsync(credential).ContinueWithOnMainThread(task =>
{
if (task.IsCanceled)
{
Debug.Log("Cancel");
}
if (task.IsFaulted)
{
Debug.Log("Faulted");
otherAuth.SignInWithCredentialAsync(credential).ContinueWithOnMainThread(linkTask =>
{
Debug.Log("Current: " + auth.CurrentUser.UserId);
Debug.Log("New: " + otherAuth.CurrentUser.UserId);
// Here both current and new have same user..
});
}
if (task.IsCompleted)
{
Debug.Log("Completed");
}
});
FirebaseApp.Create() will create the default app, you need to create a named secondary app using FirebaseApp.Create(options, name) see https://firebase.google.com/docs/reference/unity/class/firebase/firebase-app#class_firebase_1_1_firebase_app_1a39a702e1912ab6b708600b03bd955f4d
Here's an example: https://github.com/firebase/quickstart-unity/blob/master/auth/testapp/Assets/Firebase/Sample/Auth/UIHandler.cs#L97
Hi @stewartmiles
Thank you very much, using a secondary app solve my problem in all the methods except phone auth.
Now I am facing a new issue when link phone credentials. If phone auth link fails then I have used the same way to solve merge conflict.
var phoneAuthProvider = PhoneAuthProvider.GetInstance(_auth);
phoneAuthProvider.VerifyPhoneNumber(phoneNumber, PhoneAuthTimeoutMs, null,
cred =>
{
_phoneAuthCredentials = cred;
},
_user.LinkWithCredentialAsync(_phoneAuthCredentials).ContinueWithOnMainThread(HandleLinkWithUser);
_otherAuth.SignInWithCredentialAsync(_phoneAuthCredentials).ContinueWithOnMainThread(HandleMergeConflict);
After deleting the other phone auth account could you run through the VerifyPhoneNumber() step again ? I know it's a little irritating for the user but I'm sure you can pop up a message explaining what happened (e.g there was a duplicate account).
Hi @stewartmiles
This is not a proper way, because I need to VerifyPhoneNumber()
3 times.
It's very irritating for the user. My testing phone numbers are work but others do not work.
@initfusion I see what you mean, that is a pain. We'll try to get a fix out soon.
Hi @stewartmiles,
May I know ETA for this issue?
@initfusion we don't have a timeline for the change yet. I took a quick look at it last week and it's a non-trivial change to the way we store user data at the moment in the C++ SDK.
Hi,
Anyone can please help me to solve merge conflicts when link account. How to link account when the credentials already have an existing account.
Thanks.