Reputation: 29683
I am building an application wherein user can log in anonymously and later can choose to login with Google or facebook. I've followed the steps mentioned in firebase site and also this post but still am getting an error which reads -
code: "auth/provider-already-linked",
message: "User can only be linked to one identity for the given provider."
Below are my auth.service.ts contents
@Injectable()
export class AuthService {
user: Observable<User>;
constructor(private afAuth: AngularFireAuth,
private afs: AngularFirestore,
private router: Router) {
this.user = this.afAuth.authState
.switchMap(user => {
if (user) {
return this.afs.doc<User>(`usersData/${user.uid}`).valueChanges()
} else {
return Observable.of(null)
}
});
}
anonymousLogin(): Promise<any>{
return this.afAuth.auth.signInAnonymously();
}
get authState(): Observable<User>{
return this.afAuth.authState.map(data => {
return data;
});
}
get currentUser(): boolean {
return this.user !== null;
}
getCurrentUser(): User{
return this.afAuth.auth.currentUser;
}
googleLogin() {
const provider = new firebase.auth.GoogleAuthProvider()
return this.oAuthLogin(provider);
}
facebookLogin(){
const provider = new firebase.auth.FacebookAuthProvider();
provider.setCustomParameters({
'display': 'popup'
});
return this.oAuthLogin(provider);
}
private oAuthLogin(provider) {
return this.afAuth.auth.signInWithPopup(provider)
.then((response) => {
if(this.getCurrentUser() !== null){
let cred = null;
if(response.credential.providerId === 'google.com'){
cred = firebase.auth.GoogleAuthProvider
.credential(response.credential.idToken);
}else if(response.credential.providerId === 'facebook.com'){
cred = firebase.auth.FacebookAuthProvider
.credential(response.credential.authToken);
}
firebase.auth().currentUser
.linkWithCredential(cred).then(function(user) {
console.log("Anonymous account successfully upgraded", user);
}, function(error) {
console.log("Error upgrading anonymous account", error);
});
}
this.updateUserData(response.user)
});
}
private updateUserData(user) {
const userRef: AngularFirestoreDocument<any> = this.afs.doc(`usersData/${user.uid}`);
const data: User = {
uid: user.uid,
email: user.email,
displayName: user.displayName,
photoURL: user.photoURL,
isAnonymous: user.isAnonymous,
roles: {
customer: true
}
};
return userRef.set(data, {merge: true});
}
signOut() {
this.afAuth.auth.signOut().then(() => {
});
}
}
As suggested in other posts referred I've used linkWithCredential
method by passing required idToken/accessToken
but it is failing to link the accounts on both providers and hence end up creating multiple accounts under Authentication-> Users.
Could anyone please point me in the right direction or am I missing anything here?
Upvotes: 5
Views: 5962
Reputation: 30798
If you are getting auth/provider-already-linked
error code, it means you have already linked the provider to that user. You can only link a provider once. You can't have multiple Facebook accounts to the same user. Only once. If you want to remove that account, you have to unlink it: firebase.auth().currentUser.unlink(firebase.auth.FacebookAuthProvider.PROVIDER_ID)
.
You can then link a new Facebook credential to that user.
Upvotes: 6
Reputation: 4898
You can easily convert an anonymous authenticated user to a paermanent account.
View the docs here for more details. I believe that for this to work, you'll have to modify your Auth settings to allow users to login in from multiple accounts.
Upvotes: 1