Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firestore&x2B;AngularFire-链接帐户_Angular_Firebase Authentication_Angularfire2 - Fatal编程技术网

Firestore&x2B;AngularFire-链接帐户

Firestore&x2B;AngularFire-链接帐户,angular,firebase-authentication,angularfire2,Angular,Firebase Authentication,Angularfire2,我想为用户提供多个登录选项。现在谷歌和Facebook。 但当用户登录谷歌并稍后尝试登录Facebook时,我会遇到一个错误: 已存在具有相同电子邮件地址但不同的帐户 登录凭据。使用与此关联的提供程序登录 电子邮件地址 所以我必须把账户联系起来。我没有找到任何相关的文档,除了没有什么帮助。我能找到的最好的信息就在这里,但出于某种原因,这对我来说还不够。 该解决方案处理带有弹出窗口的登录,这会导致以下错误: “无法与弹出窗口建立连接。它可能已被删除。” 已被浏览器阻止。“ 因此,如果弹出窗口不起作

我想为用户提供多个登录选项。现在谷歌和Facebook。 但当用户登录谷歌并稍后尝试登录Facebook时,我会遇到一个错误:

已存在具有相同电子邮件地址但不同的帐户 登录凭据。使用与此关联的提供程序登录 电子邮件地址

所以我必须把账户联系起来。我没有找到任何相关的文档,除了没有什么帮助。我能找到的最好的信息就在这里,但出于某种原因,这对我来说还不够。 该解决方案处理带有弹出窗口的
登录,这会导致以下错误:

“无法与弹出窗口建立连接。它可能已被删除。” 已被浏览器阻止。“ 因此,如果弹出窗口不起作用,我将调用signInWithRedirect:

弹出后,您将进入
,然后
并可以执行任何操作。但重定向后,您会丢失信息。所以我把它存储在
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);
          });
      }
    }
  });
}
构造函数(
私人afAuth:AngularFireAuth,
私人afs:AngularFirestore,
) {
this.afAuth.auth.getRedirectResult()。然后(结果=>{
if(result.user){
this.credential=result.credential;
const authror=JSON.parse(localStorage.getItem('auth_error');
如果(authError){
localStorage.removietem('auth_error');
this.afAuth.auth.signiWithCredential(
firebase.auth.GoogleAuthProvider.credential(
空,(:

使用需要调用的访问令牌调用带有凭据的登录时 它是这样的:

使用凭据(空,令牌)登录;
如果您正在执行
使用凭证(令牌)登录
然后您需要使用ID令牌,而不是 而不是访问令牌

我尝试了两个版本,均未成功。第二个版本:
this.afAuth.auth.signiWithCredential(firebase.auth.GoogleAuthProvider.credential((this.credential.idToken))
类型转换之所以存在,是因为我想类型定义中存在问题

我尝试插入整个
credentials
对象,将
idToken
作为第一个参数,将
accessToken
作为第二个参数。但我始终得到: 第一个参数“凭证”必须是有效凭证。

在我写这篇文章时,我突然想到这可能是
linkWithCredential
的问题,而不是
signInWithCredential
方法的问题。根据错误消息,这应该是显而易见的。我只是没有注意到,因为谷歌搜索错误给了我解决方案。所以我很快检查了
authorror中的内容
变量。有
accessToken
providerId
SigningMethod
方法。没有
tokenId
。因此我尝试将
accessToken
作为参数发送,而不是整个对象,但没有帮助。我尝试将其作为
null,accessToken
发送。没有帮助。我尝试查找文档对于
linkWithCredential
方法,我没有任何运气。所以我不知道它期望什么


我已经为此浪费了四天时间。这让我的精神健康付出了很大代价。有人能帮我吗?

您可以存储底层OAuth凭据(id令牌或访问令牌):
error.credential.idToken
error.credential.accessToken
及其提供程序ID
error.credential.providerId
。返回到页面时,您可以重新初始化凭据,例如:
firebase.auth.FacebookAuthProvider.credential(accessToken)
。成功重定向谷歌登录后,链接该凭证

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);
          });
      }
    }
  });
}