Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从console.firebase.google.com取消用户后,用户身份验证持续存在_Java_Android_Firebase_Firebase Realtime Database_Firebase Authentication - Fatal编程技术网

Java 从console.firebase.google.com取消用户后,用户身份验证持续存在

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上的重新加载 从文档中可以看出,这会引发异常,但不会发生。发生的情况

如果我直接从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规则来限制访问。那么你是说上面的代码工作得很好,但可能有一些不工作的机会?因为到目前为止,在我的应用程序中,此代码正在工作。它看起来像是。重新加载刷新用户令牌。不,您的代码将始终工作。我想说的是,从您从控制台手动删除用户到您获得刷新令牌的时间,可能长达一个小时,在这段时间内,用户仍然可以访问您的应用程序,即使他已被删除。要停止这一过程,在这一小时内,您需要使用上面的解决方案。