我想为用户提供多个登录选项。目前,谷歌和Facebook。
但当用户登录Google并稍后尝试登录Facebook时,我会遇到一个错误:
已存在具有相同电子邮件地址但不同的帐户
登录凭据。使用与此关联的提供程序登录
电子邮件地址。
所以我必须把账户联系起来。我没有找到任何相关文档,除了
this
这没什么帮助。我能找到的最好的信息是
stackoverflow
但出于某种原因,这对我来说还不够。
解决方案涉及
signInWithPopup
这给了我一个错误:
“无法与弹出窗口建立连接。可能是
被浏览器阻止。“”
因此,如果弹出窗口不起作用,我将调用signInWithRedirect:
private authLoginWithPopup(provider: AuthProvider) {
this.afAuth.auth.signInWithPopup(provider)
.then((result) => {
this.credential = result.credential;
this.updateUserData(result);
})
.catch(error => {
if (error.code === 'auth/account-exists-with-different-credential') {
this.mergeCredentials(error);
} else if (error.code === 'auth/popup-blocked') {
this.authLoginWithRedirect(new firebase.auth.GoogleAuthProvider());
}
});
}
弹出后,您将进入
then
可以做任何事。但重定向后,您会丢失信息。所以我把它储存在
localStorage
:
this.afAuth.auth.fetchProvidersForEmail(error.email).then(providers => {
const [ provider ] = providers;
if (provider === 'google.com') {
const googleProvider = new firebase.auth.GoogleAuthProvider();
googleProvider.setCustomParameters({ login_hint: error.email });
localStorage.setItem('auth_error', JSON.stringify(error.credential));
this.authLoginWithPopup(googleProvider);
}
});
我在getRedirectResult中检索它:
constructor(
private afAuth: AngularFireAuth,
private afs: AngularFirestore,
) {
this.afAuth.auth.getRedirectResult().then(result => {
if (result.user) {
this.credential = result.credential;
const authError = JSON.parse(localStorage.getItem('auth_error'));
if (authError) {
localStorage.removeItem('auth_error');
this.afAuth.auth.signInWithCredential(
firebase.auth.GoogleAuthProvider.credential(
null, (<any>this.credential).accessToken
)
)
.then(user => {
user.linkWithCredential(authError)
})
.catch(error => {
console.log('error', error);
});
}
}
});
}
(这会产生另一个问题。我如何知道这是一个直接登录Google的用户的正常登录重定向。还是一个在用户尝试登录Facebook并由于此错误被提示登录Google后的重定向?我不想每次都合并凭据。但这是一个较小的问题。但我也希望找到解决此问题的方法。)
但是
signInWithCredential
给我这个错误:
linkWithCredential失败:第一个参数“credential”必须是有效的
资质
我找到了“解决方案”
here
:
呼叫时
使用凭据登录
使用需要调用的访问令牌
它是这样的:
signInWithCredential(null, token);
如果你正在做
signInWithCredential(token)
那么您需要使用ID标记,而不是
而不是访问令牌。
我尝试了两种版本,都没有成功
.第二版:
this.afAuth.auth.signInWithCredential(firebase.auth.GoogleAuthProvider.credential((<any>this.credential).idToken))
类型转换之所以存在,是因为我想类型定义中存在问题。
我试着插入整个
credentials
对象
idToken
作为第一个参数,
accessToken
作为第二个参数。但我总是得到:
第一个参数“credential”必须是有效的凭据。
在我写这篇文章的时候,我突然想到这可能是
linkWithCredential
而不是
使用凭据登录
方法根据错误消息,这应该是显而易见的。我只是没有注意到,因为谷歌搜索错误给了我这个解决方案。所以我很快检查了
authError
变量有
accessToken
,则,
providerId
和
signInMethod
方法没有
tokenId
.所以我试着
accessToken
作为一个参数,而不是整个对象,它没有帮助。我试着把它作为
null, accessToken
.没有帮助。我试图找到的文档
linkWithCredential链接
方法,没有任何运气。所以我不知道它在期待什么。
我已经在这上面浪费了四天了。这让我失去了很多精神健康。谁能帮帮我吗?