Java 从console.firebase.google.com取消用户后,用户身份验证持续存在
如果我直接从Firebase控制台删除一个用户,该用户在我的Android设备上仍然拥有有效数据 当然,如果我随后访问firebase资源,例如无法按预期工作的实时数据库 但这会导致客户机中出现错误,因为如果我有有效的用户数据,我会为经过身份验证的用户显示一个特定的UI,而如果我没有经过身份验证的用户,我会显示另一个UI 我如何处理这种情况 编辑:我发现了什么,但我现在不知道这是否可以,或者解决方法是调用FirebaseUser上的重新加载 从文档中可以看出,这会引发异常,但不会发生。发生的情况是,我的用户引用变为空:Java 从console.firebase.google.com取消用户后,用户身份验证持续存在,java,android,firebase,firebase-realtime-database,firebase-authentication,Java,Android,Firebase,Firebase Realtime Database,Firebase Authentication,如果我直接从Firebase控制台删除一个用户,该用户在我的Android设备上仍然拥有有效数据 当然,如果我随后访问firebase资源,例如无法按预期工作的实时数据库 但这会导致客户机中出现错误,因为如果我有有效的用户数据,我会为经过身份验证的用户显示一个特定的UI,而如果我没有经过身份验证的用户,我会显示另一个UI 我如何处理这种情况 编辑:我发现了什么,但我现在不知道这是否可以,或者解决方法是调用FirebaseUser上的重新加载 从文档中可以看出,这会引发异常,但不会发生。发生的情况
private void initializeUI(FirebaseUser user) {
user.reload();
if (null != user) {
mUser = user;
} else {
// User must have been disabled or deleted from console
}
我在这里称之为initializeUI:
@Override
public void onAuthStateChanged(@NonNull final FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (null != user) {
initializeSignInUI(user);
} else {
initializeSignOutUI();
}
}
更多信息:
如果我打开我的应用程序,用户在客户端仍处于活动状态。身份验证用户的触发器被触发,在这里,通过上面的代码,我可以处理这种情况。但我不知道这究竟是一种解决方法还是正确的做法
编辑2
我想重新解释一下我的问题:
这种方法很有效:
public boolean validUser(FirebaseUser user) {
boolean validUser = false;
if (null != user) {
try {
user.reload();
if (null != user) {
validUser = true;
}
} catch (Exception e) {
//} catch (FirebaseAuthInvalidUserException e) {
validUser = false;
}
}
return validUser;
}
我能不能认为这是一个有效的解决办法?还是另一个最好的做法?此解决方案仅适用于FirebaseAuth,无需与FirebaseDatabase交互。
每次需要检查用户身份验证时,我都可以调用此方法。如果您的用户在应用程序中登录,并且您正在从Firebase控制台手动删除它,则用户将保持活动状态,直到令牌刷新。因此,最多一个小时,用户将保持身份验证。因此,如果你想立即限制用户的访问,你需要让他退出 但还有另一种解决方法,您可以在Firebase数据库中创建一个名为usersToLogOut的新节点,并在其中添加所有用户ID作为键,布尔值true作为值。数据库应如下所示:
Firebase-root
|
--- usersToLogOut
|
--- uid1: true
|
--- uid2: true
{
"rules": {
"usersToLogOut": {
".read": true,
".write": false
},
"posts": {
".read": "auth != null && !root.child('usersToLogOut').child(auth.uid).exists()"
}
}
}
下一步,当您手动删除该帐户时,需要在此节点下添加用户的uid。您还需要使用Firebase安全规则来撤销未经授权用户的访问权限。规则应如下所示:
Firebase-root
|
--- usersToLogOut
|
--- uid1: true
|
--- uid2: true
{
"rules": {
"usersToLogOut": {
".read": true,
".write": false
},
"posts": {
".read": "auth != null && !root.child('usersToLogOut').child(auth.uid).exists()"
}
}
}
编辑1:
根据你的编辑,你说:我在这里问的不是如何从他/她那里保护我的DB,而是我要检查它是否已被删除,但这是通过使用上述规则实现这一点的更简单的方法。如果您从控制台手动删除该用户,这并不意味着您正在删除该用户的所有内容,包括数据库记录。你需要自己做这件事。所以最简单的方法就是使用规则
此外,如果您删除了所有用户记录,那么您可以添加一个侦听器并强制他注销,但这意味着您需要在数据库中搜索所有记录并相应地删除它们。第一个解决方案更简单,因为您只需要在数据库中添加一条记录,就这样
编辑2:
手动删除用户时,这并不意味着firebaseUser对象将为空,因此检查空值没有任何意义,因为在下一次令牌刷新之前,用户仍将通过身份验证。所以要解决这个问题,需要使用Firebase规则来限制访问
因此,您的代码将始终有效。我想说的是,从您从控制台手动删除用户到您获得刷新令牌的时间,可能长达一个小时,在这段时间内,用户仍然可以访问您的应用程序,即使他已被删除。要停止这一过程,在这一小时内,您需要使用上面的解决方案
编辑3根据OP的评论:
您的代码运行良好,并且始终可以正常工作,但问题是,即使您从控制台中删除用户,在下一次令牌刷新之前,他仍然可以访问数据库。是的,用户将能够访问数据库。该令牌将在大约一小时内有效,如果您不想这样,您可以限制使用安全规则,并且在该小时内用户不再具有访问权限
换句话说,如果您也从客户端删除它,如果它无效,并且如果其他人“窃取”了该令牌,则可以使用它访问数据库。不是正在使用你的应用程序的用户,而是可能偷了该令牌的人。如果你的用户在你的应用程序中登录,并且你正在从Firebase控制台手动删除该令牌,则该用户将保持活动状态,直到令牌被刷新。因此,最多一个小时,用户将保持身份验证。因此,如果你想立即限制用户的访问,你需要让他退出 但还有另一种解决方法,您可以在Firebase数据库中创建一个名为usersToLogOut的新节点,并在其中添加所有用户ID作为键,布尔值true作为值。数据库应如下所示:
Firebase-root
|
--- usersToLogOut
|
--- uid1: true
|
--- uid2: true
{
"rules": {
"usersToLogOut": {
".read": true,
".write": false
},
"posts": {
".read": "auth != null && !root.child('usersToLogOut').child(auth.uid).exists()"
}
}
}
下一步,当您手动删除该帐户时,您需要添加
此节点下的e用户。您还需要使用Firebase安全规则来撤销未经授权用户的访问权限。规则应如下所示:
Firebase-root
|
--- usersToLogOut
|
--- uid1: true
|
--- uid2: true
{
"rules": {
"usersToLogOut": {
".read": true,
".write": false
},
"posts": {
".read": "auth != null && !root.child('usersToLogOut').child(auth.uid).exists()"
}
}
}
编辑1:
根据你的编辑,你说:我在这里问的不是如何从他/她那里保护我的DB,而是我要检查它是否已被删除,但这是通过使用上述规则实现这一点的更简单的方法。如果您从控制台手动删除该用户,这并不意味着您正在删除该用户的所有内容,包括数据库记录。你需要自己做这件事。所以最简单的方法就是使用规则
此外,如果您删除了所有用户记录,那么您可以添加一个侦听器并强制他注销,但这意味着您需要在数据库中搜索所有记录并相应地删除它们。第一个解决方案更简单,因为您只需要在数据库中添加一条记录,就这样
编辑2:
手动删除用户时,这并不意味着firebaseUser对象将为空,因此检查空值没有任何意义,因为在下一次令牌刷新之前,用户仍将通过身份验证。所以要解决这个问题,需要使用Firebase规则来限制访问
因此,您的代码将始终有效。我想说的是,从您从控制台手动删除用户到您获得刷新令牌的时间,可能长达一个小时,在这段时间内,用户仍然可以访问您的应用程序,即使他已被删除。要停止这一过程,在这一小时内,您需要使用上面的解决方案
编辑3根据OP的评论:
您的代码运行良好,并且始终可以正常工作,但问题是,即使您从控制台中删除用户,在下一次令牌刷新之前,他仍然可以访问数据库。是的,用户将能够访问数据库。该令牌将在大约一小时内有效,如果您不想这样,您可以限制使用安全规则,并且在该小时内用户不再具有访问权限
换句话说,如果您也从客户端删除它,如果它无效,并且如果其他人“窃取”了该令牌,则可以使用它访问数据库。不是正在使用你的应用程序的用户,而是可能偷了该令牌的人。要检查该用户是否已在数据库中被删除,请尝试以下操作:
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
String useruid=user.getUid();
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users").child(useruid);
ref.addValueEventListener(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists()){
//update UI
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
上面将检查useruid是否存在,并且由于您也在从数据库中删除,因此将找不到它,然后您可以使用setVisiblity更新UI
假设您在DB中有此项:
users
useruid
username: userx
email: userx@gmail.com
useruid
username: usery
email:usery@gmail.com
要检查该用户是否已在数据库中删除,请尝试以下操作:
FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
String useruid=user.getUid();
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("users").child(useruid);
ref.addValueEventListener(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(!dataSnapshot.exists()){
//update UI
}
}
@Override
public void onCancelled(FirebaseError firebaseError) {
}
});
上面将检查useruid是否存在,并且由于您也在从数据库中删除,因此将找不到它,然后您可以使用setVisiblity更新UI
假设您在DB中有此项:
users
useruid
username: userx
email: userx@gmail.com
useruid
username: usery
email:usery@gmail.com
数据库中是否有用户节点?登录后,在“身份验证”部分中创建了用户,我在数据库中创建了用户节点,是的。但是当我从控制台中删除时,我有一个触发器,它也会清理我的DB。可能是@AL的副本。我的场景完全不同。我编辑了我的答案,以便更好地解释这个场景。如果我的设备中有一个已经过身份验证的用户,并且我从控制台中删除了它,那么我在这里要问的不是如何从他/她那里保护我的数据库,而是检查它是否已被删除以更新我的用户界面,并在没有用户身份验证的情况下更新我的环境。@AL。因此,我认为这不是重复的。我要求更多。数据库中是否有用户节点?登录后,在“身份验证”部分创建用户,我在数据库中创建用户节点,是的。但是当我从控制台中删除时,我有一个触发器,它也会清理我的DB。可能是@AL的副本。我的场景完全不同。我编辑了我的答案,以便更好地解释这个场景。如果我的设备中有一个已经过身份验证的用户,并且我从控制台中删除了它,那么我在这里要问的不是如何从他/她那里保护我的数据库,而是检查它是否已被删除以更新我的用户界面,并在没有用户身份验证的情况下更新我的环境。@AL。因此,我认为这不是重复的。我要求更多。嗨,Alex,如果你看一下我的其他编辑,我已经建立了。一个不包含访问数据库的方法,但是只处理FirebaseAuth。我已经从DB端找到了清理被删除用户的所有触发器。我看到了这一点,这就是为什么我会相应地回答你。手动删除用户时,这并不意味着firebaseUser对象将为空,因此检查空值没有任何意义,因为在下一次令牌刷新之前,用户仍将通过身份验证。所以要解决这个问题,你需要使用Firebase规则来限制访问。那么你是说上面的代码工作得很好,但可能有一些不工作的机会?因为到目前为止,在我的应用程序中,此代码正在工作。它看起来像是。重新加载刷新用户令牌。不,您的代码将始终工作。我想说的
从您从控制台手动删除用户到您获得刷新令牌的时间,可能长达一个小时,即使用户被删除,用户仍可以访问您的应用程序。为了阻止这种情况,在这一小时内,你需要使用上面的解决方案。嗨,Alex,如果你看一下我的另一个编辑,我已经构建了。一个不包括访问数据库但在上的方法只处理FirebaseAuth。我已经从DB端找到了清理被删除用户的所有触发器。我看到了这一点,这就是为什么我会相应地回答你。手动删除用户时,这并不意味着firebaseUser对象将为空,因此检查空值没有任何意义,因为在下一次令牌刷新之前,用户仍将通过身份验证。所以要解决这个问题,你需要使用Firebase规则来限制访问。那么你是说上面的代码工作得很好,但可能有一些不工作的机会?因为到目前为止,在我的应用程序中,此代码正在工作。它看起来像是。重新加载刷新用户令牌。不,您的代码将始终工作。我想说的是,从您从控制台手动删除用户到您获得刷新令牌的时间,可能长达一个小时,在这段时间内,用户仍然可以访问您的应用程序,即使他已被删除。要停止这一过程,在这一小时内,您需要使用上面的解决方案。