在用户第二次进行身份验证后,使用新的用户 ID 更新文档



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

  1. 新用户到达网站
  2. 用户会收到匿名登录从 Firebase 获得user.uid
  3. 用户
  4. 创建一个文档,其作为用户ID引用上述user.uid
  5. 在同一页面中,邀请用户登录,否则文档将丢失
  6. 用户登录并找到帐户文档

赢!

现在我有一个用例无法按预期工作:

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

这次没有赢

:(我使用以下配置配置了火力基础身份验证:

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

谢谢。

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

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

我找到了这个使用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>');
});
}

最新更新