【问题标题】:Firebase Realtime Database delete specific userFirebase 实时数据库删除特定用户
【发布时间】:2019-04-18 17:44:49
【问题描述】:

我希望从我的数据库中删除电话号码为 X 的特定用户。并插入我的代码删除所有这些。

这是我的数据库:

代码:

    private static void deleteUser(final Context context, final String phoneNumber) {

        DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference("users");
        Query usersQuery = databaseReference.orderByChild("phone").equalTo(phoneNumber);

        usersQuery.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                dataSnapshot.getRef().removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {

                        Log.d(TAG, "Deleted");

                    }
                });

            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.d(TAG, "onCancelled", databaseError.toException());
            }


        });
    }

【问题讨论】:

  • 您必须循环使用 dataSnapshot 中数据的子节点,使用如下增强的 for 循环:for(DataSnapshot ds : dataSnapshot.getChildren()) { ... }
  • 但是如果我总是只有 1 个具有这个特定值的孩子呢?我还需要添加启动某些功能的“addOnCompleteListener”。通过循环,它将为每个用户触发“addOnCompleteListener”。我不希望它发生。当然,我说过我最多有 1 个用户使用这款特定的手机,但以防万一我不创建循环。
  • 请看我的回答@Dim,看看这是否能解释你的问题。

标签: android firebase firebase-realtime-database


【解决方案1】:

也许我的评论不清楚,所以我把这个作为答案,不应该有你面临的问题的完整代码应该是这样的:

usersQuery.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                  for (DataSnapshot ds: dataSnapshot.getChildren()) {                
                         ds.getRef().removeValue().addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {

                                 Log.d(TAG, "Deleted");

                            }
                         });

                  }
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {
                Log.d(TAG, "onCancelled", databaseError.toException());
            }


        });

那是因为您使用的是singleValueEventListener。如果查询匹配多个孩子,它会返回所有这些孩子的列表。

即使只有一个匹配子项,它仍然是一个列表。由于您在该列表中调用 getRef(),因此您将获得运行查询的位置的键。

【讨论】:

  • 好的,但是.... 假设在删除用户后我希望开始新的活动。所以我在“onComplete”中的代码是startActivity(intent)。如果我有 2 个用户使用相同的电话号码。函数“startActivity(intent)”将被调用两次。我错了吗?
  • 阅读我回答的最后几行,问题是当您调用dataSnapshot.getKey() 时,如果查询匹配多个子节点,它会给出所有子节点的列表,但是,有趣的是是即使它只匹配一个子节点,它仍然返回一个列表,其getKey() 为您提供主父键users,然后调用removeValue(),从而删除整个列表。但是,当您遍历子节点时,您只会得到子节点的父节点存在于一个列表中,因此,这为您提供了删除用户所需的正确参考。
  • 谢谢,加油!
  • 不用担心,很高兴为您提供帮助:)
  • ds.getKey() 返回一个字符串,您无法在其上调用removeValue()。您应该使用getRef() getKey()
猜你喜欢
  • 2020-07-16
  • 2020-01-17
  • 1970-01-01
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 2019-01-24
  • 1970-01-01
  • 2021-06-04
相关资源
最近更新 更多