我有以下按预期使用的用例:
user.uid
user.uid
获胜!
现在我有一个用例无法按预期工作:
user.uid
user.uid
这次没有胜利:(
我使用以下配置配置了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
谢谢。
答案 0 :(得分:0)
问题是您无法使用相同的凭据创建新用户。如果用户登录,他将从匿名登录中删除数据。
您必须在本地保存来自匿名用户的数据,并且在用户登录后,必须将数据复制到当前用户。您还应该删除匿名帐户。
我已经找到了使用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>');
});
}