【问题标题】:Update document with new userId after user authenticated for the second time在第二次用户认证后使用新用户 ID 更新文档
【发布时间】:2019-04-22 16:41:10
【问题描述】:

我有以下按预期工作的用例:

  1. 新用户到达网站
  2. 用户从 firebase 匿名登录获得 user.uid
  3. 用户创建了一个文档,其中 userId 引用了上述user.uid
  4. 在同一页面上邀请用户登录,否则文档将丢失
  5. 用户登录后发现是账户文件

赢了!

现在我有一个未按预期工作的用例:

  1. 会话已过期或来自其他浏览器的返回用户到达网站
  2. 用户通过 firebase 匿名登录获得 user.uid
  3. 用户创建了一个文档,其中 userId 引用了上述user.uid
  4. 在同一页面上邀请用户登录,否则文档将丢失
  5. 用户登录后没有找到帐户文档

这次没赢:(

我使用以下配置配置了 Firebase 身份验证:

const uiConfig = {
  signInFlow: 'popup',
  autoUpgradeAnonymousUsers: true,
  signInOptions: [
    firebase.auth.GoogleAuthProvider.PROVIDER_ID,
  ],
  callbacks: {
    signInFailure: (error: any) => {
      if (error.code != 'firebaseui/anonymous-upgrade-merge-conflict') {
        return Promise.resolve();
      }
      var cred = error.credential;
      return firebase.auth().SignInAndRetrieveDataWithCredential(cred);
    }

  },
};

所以,如您所见,问题在于,第一次,autoUpgradeAnonymousUsers 使用匿名用户 ID 创建了一个新的 userId,一切都很好,但当然第二次不再起作用了。

鉴于我想在我的安全规则中创建一个检查 userId 无法更新并且只有具有相同 userId 的请求才能看到文档,我应该如何解决这个问题?

安全规则:

allow create: if request.auth.uid != null
allow read: if request.auth.uid == resource.data.userId 
                    && request.auth.uid != null
allow update: if request.auth.uid == request.resource.data.userId && resource.data.userId == request.resource.data.userId && request.auth.uid != null

谢谢。

【问题讨论】:

  • 您在第二个用例中尝试实现什么?如果用户没有创建永久帐户,您想从第一个用例中恢复文档吗?
  • 不,不是。我最初的想法是不要在第一次登录之前丢失 userId 信息。第二个用例是我没有想到的边缘案例。
  • 嗯,我不明白为什么这不起作用。如果您匿名登录,您应该始终获得一个新的 uid。你能重现这种行为吗?你能展示更多你的代码吗?
  • 如果您使用启用匿名登录时可用的 autoMerge 功能,则用户第一次进行身份验证时,匿名 uid 将用于登录用户,并且它们将是相同的。如果您注销并再次登录,那么用户 ID 当然会更改。实际上,这就是将匿名自动合并到登录用户所需的代码。您具体需要什么作为附加代码?

标签: firebase firebase-authentication google-cloud-firestore firebase-security


【解决方案1】:

问题是您无法使用相同的凭据创建新用户。如果用户登录,他会丢失匿名登录的数据。

您必须将来自匿名用户的数据保存在本地,并且在用户登录后,您必须将数据复制到当前用户。您还应该删除匿名帐户。

我发现了这个使用 Firebase 实时数据库来保存用户数据的例子。

https://github.com/firebase/firebaseui-web#upgrading-anonymous-users

    // signInFailure callback must be provided to handle merge conflicts which
    // occur when an existing credential is linked to an anonymous user.
    signInFailure: function(error) {
      // For merge conflicts, the error.code will be
      // 'firebaseui/anonymous-upgrade-merge-conflict'.
      if (error.code != 'firebaseui/anonymous-upgrade-merge-conflict') {
        return Promise.resolve();
      }
      // The credential the user tried to sign in with.
      var cred = error.credential;
      // If using Firebase Realtime Database. The anonymous user data has to be
      // copied to the non-anonymous user.
      var app = firebase.app();
      // Save anonymous user data first.
      return app.database().ref('users/' + firebase.auth().currentUser.uid)
          .once('value')
          .then(function(snapshot) {
            data = snapshot.val();
            // This will trigger onAuthStateChanged listener which
            // could trigger a redirect to another page.
            // Ensure the upgrade flow is not interrupted by that callback
            // and that this is given enough time to complete before
            // redirection.
            return firebase.auth().signInWithCredential(cred);
          })
          .then(function(user) {
            // Original Anonymous Auth instance now has the new user.
            return app.database().ref('users/' + user.uid).set(data);
          })
          .then(function() {
            // Delete anonymnous user.
            return anonymousUser.delete();
          }).then(function() {
            // Clear data in case a new user signs in, and the state change
            // triggers.
            data = null;
            // FirebaseUI will reset and the UI cleared when this promise
            // resolves.
            // signInSuccessWithAuthResult will not run. Successful sign-in
            // logic has to be run explicitly.
            window.location.assign('<url-to-redirect-to-on-success>');
          });

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-13
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多