【问题标题】:How to prevent multiple account for same user in Firebase?如何防止 Firebase 中同一用户的多个帐户?
【发布时间】:2020-12-24 23:36:09
【问题描述】:

我们正在使用 Flutter 开发应用程序并探索 Firebase 进行身份验证,我们计划向最终用户提供以下身份验证机制。

  1. 通过 OTP 登录
  2. 社交登录 (Facebook/Google)

但是有一个问题,在下面的场景中。

  1. 用户通过 OTP 登录(创建一个新帐户),假设 U1(用户 ID)和 M1(移动)

    U1 ----> M1

  2. 现在另一天,同一用户尝试通过 FaceBook 登录(我们不会通过社交登录获得移动设备),只有电子邮件将在那里,现在将为同一用户创建一个新帐户。

    U2 -----> E1

如何防止在第 2 步 (U2) 中创建帐户,作为其同一用户?

试图探索,在 OTP 验证后通过电话号码更新用户个人资料,以防社交登录,但看起来无法添加电话号码,以防该号码的帐户已经存在。

如果已经存在具有给定电话号码的帐户,则会引发 FirebaseAuthUserCollisionException

https://firebase.google.com/docs/reference/android/com/google/firebase/auth/FirebaseUser#updatePhoneNumber(com.google.firebase.auth.PhoneAuthCredential)

有人可以帮忙吗?有人在使用 Firebase 身份验证时遇到过类似问题吗?

【问题讨论】:

  • 根据您所解释的流程,将始终创建两个帐户,因为没有共同因素可以确定编号。和电子邮件是同一用户。没有办法默认创建两个帐户。如果使用社交登录的用户登录添加了关联手机号码的功能。与帐户,然后根据帐户链接文档链接这两个帐户。当用户使用移动 otp 登录时,可以选择将他们的社交帐户与之关联..

标签: firebase flutter firebase-authentication


【解决方案1】:

您需要找到一种方法来识别这是同一用户,然后是link their Phone and Facebook accounts together

将帐户识别为来自同一用户的惯用方法是通过他们的电子邮件地址。这意味着您必须要求 Phone auth 用户提供电子邮件地址,然后提供set that email address on the account

【讨论】:

  • 是的,但是将电子邮件添加到电话身份验证帐户本质上是异步的(必须将验证链接发送到电子邮件,并且一旦用户单击 gthat 链接,则只能添加该电子邮件),用户可以随时退出并使用社交(Google/Facebook)登录。有什么方法可以在社交登录期间添加电话号码,而不是将这个帐户链接到以前的帐户(电话身份验证)?
【解决方案2】:

我能够解决这个问题。

1. Login Social account (Account_2)
2. Try to link Mobile No
    If(Success)
       Account (Step1) updated with Mobile No
    Else
       Login with Mobile No (Account_1)
       Link Social account (Account_2) created in step1 with Account_1

示例 java 脚本代码:

    <script>
  var firebaseConfig = {
    apiKey: "XXXX",
    authDomain: "XXXXXX",
    databaseURL: "XXXXXX",
    projectId: "XXXXXX",
    storageBucket: "XXXXXXXXX",
    messagingSenderId: "XXXXXXX",
    appId: "XXXXXXXX",
    measurementId: "XXXXXXXXXXXX"
  };

  firebase.initializeApp(firebaseConfig);
  firebase.analytics();


var provider = new firebase.auth.FacebookAuthProvider;

var phoneAuthProvider = new firebase.auth.PhoneAuthProvider;

firebase.auth().useDeviceLanguage();

provider.setCustomParameters({
  'display': 'popup'
});

var globalCred ;


firebase.auth().signInWithPopup(provider).then(function(result) {

  var token = result.credential.accessToken;

  globalCred = result.credential;

  console.log("GLOBAL :" + globalCred);

  var user = result.user;

  var prevUser = firebase.auth().currentUser; //Logged in via FB
  
  console.log(prevUser);

  
  if (!user.phoneNumber) {
      // Ask user for phone number.
      var phoneNumber = window.prompt('Provide your phone number');
      // You also need to provide a button element signInButtonElement
      // which the user would click to complete sign-in.
      // Get recaptcha token. Let's use invisible recaptcha and hook to the button.
      var appVerifier = new firebase.auth.RecaptchaVerifier(
          signInButtonElement, {size: 'invisible'});
      // This will wait for the button to be clicked the reCAPTCHA resolved.
      return result.user.linkWithPhoneNumber(phoneNumber, appVerifier)
        .then(function(confirmationResult) {
          // Ask user to provide the SMS code.
          var code = window.prompt('Provide your SMS code');
          // Complete sign-in.
          return confirmationResult.confirm(code);
        })
    }

}).catch(function(error) {

  var errorCode = error.code;
  var errorMessage = error.message;

  var email = error.email;

  var credential = error.credential;

  if(errorCode == 'auth/credential-already-in-use'){
      // Merge accounts      
      console.log("Trying Linking");  

      var prevUser = firebase.auth().currentUser;

      prevUser.delete().then(function() {
        console.log("FB user deleted");
      }).catch(function(error) {
        // An error happened.
        console.log("Error in FB user deletion");
      });

      firebase.auth().signInWithCredential(credential).then(function(result) {
        console.log("Sign In Success using Phone", result);
        var currentUser = result.user;

          firebase.auth().currentUser.linkWithCredential(globalCred);

          });

      }).catch(function(error) {
        // If there are errors we want to undo the data merge/deletion
        console.log("Sign In Error", error);
        //repo.set(prevUser, prevUserData);
      });


  }

}); 

</script>

【讨论】:

    猜你喜欢
    • 2016-06-29
    • 2018-05-24
    • 1970-01-01
    • 2010-09-15
    • 1970-01-01
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    相关资源
    最近更新 更多