简体   繁体   English

如何从Firebase数据库中删除用户

[英]How to delete a User from Firebase Database

so I wanted to add the functionality for a user to delete his account to my app.. simple right? 所以我想为用户添加功能以将其帐户删除到我的应用中。 I look in documentation, and its easy enough: 我看一下文档,它很简单:

FirebaseAuth.getInstance().getCurrentUser().delete()

But then all his data in FirebaseDatabase and Storage remains. 但是,他在FirebaseDatabase和Storage中的所有数据仍然保留。 This is my structure (give or take) 这是我的结构(给予或接受) 在此处输入图片说明

In firebase storage its a bit simpler, so I don't include in this question.. 在Firebase存储中,它要简单一些,因此我不在此问题之列。

Now the problem is, the user is associated with almost all nodes somehow, and there is a lot of places he needs to be deleted. 现在的问题是,用户几乎以某种方式与几乎所有节点相关联,并且有很多地方需要删除。 From android device user sends "DeleteUserRequest" to server, and server takes care of delete the user. 用户从android设备向服务器发送“ DeleteUserRequest”,服务器负责删除用户。 But after make the method, its hell!!! 但是在制定了方法之后,该死的!!! I needed to borrow dad's monitor to code it because soo deep nested calls! 我需要借用父亲的监视器进行编码,因为嵌套调用太深了!

here is the method 这是方法

public static void deleteUser(DeleteUserRequest request, ExecutorService executorService) {
    deleteUserReferences(request.getUserId(), executorService);
    deleteUserStorage(request.getUserId());
}

/**
 * Delete Tree
 * - /grades/userId
 * - /subjects/userId
 * - /user_groups/userId -> save groupIdList
 * - /group_members/groupId/userId
 * - /groups/groupId/ [where createdBy=userId] <- Delete that Group using GroupRequestManager
 * - /user_friends/userId -> save friendIdList
 * - /user-friends/friendId/userId
 * - /user_tokens/userId
 * - /users/userId
 * - /friend_requests/userId
 * - /friend_requests/friendUserId/userId
 */
private static void deleteUserReferences(final String userId, ExecutorService executorService) {
    final MultiPathUpdate deleteUpdate = new MultiPathUpdate(FirebaseDatabase.getInstance().getReference());
    FirebaseDatabase.getInstance().getReference()
            .child(DatabaseConstants.LOCATION_GROUPS)
            .orderByChild(DatabaseConstants.PROPERTY_CREATED_BY)
            .equalTo(userId)
            .addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    final ArrayList<String> groupIdsWhereAdmin = new ArrayList<>();
                    if (dataSnapshot.exists()) {
                        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                            groupIdsWhereAdmin.add(snapshot.getKey());
                        }
                    }
                    for (String groupId : groupIdsWhereAdmin) {
                        GroupRequestManager.deleteGroup(new DeleteGroupRequest(groupId, userId), executorService);
                    }
                    FirebaseDatabase.getInstance().getReference()
                            .child(DatabaseConstants.LOCATION_USER_GROUPS)
                            .child(userId)
                            .addListenerForSingleValueEvent(new ValueEventListener() {
                                @Override
                                public void onDataChange(DataSnapshot dataSnapshot) {
                                    if (dataSnapshot.exists()) {
                                        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                                            final String groupId = snapshot.getKey();
                                            deleteUpdate.delete(new ChildLocation()
                                                    .child(DatabaseConstants.LOCATION_GROUP_MEMBERS)
                                                    .child(groupId)
                                                    .child(userId));
                                        }
                                    }
                                    FirebaseDatabase.getInstance().getReference()
                                            .child(DatabaseConstants.LOCATION_USER_FRIENDS)
                                            .child(userId)
                                            .addListenerForSingleValueEvent(new ValueEventListener() {
                                                @Override
                                                public void onDataChange(DataSnapshot dataSnapshot) {
                                                    if (dataSnapshot.exists()) {
                                                        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                                                            final String friendId = snapshot.getKey();
                                                            deleteUpdate.delete(new ChildLocation()
                                                                    .child(DatabaseConstants.LOCATION_USER_FRIENDS)
                                                                    .child(friendId)
                                                                    .child(userId));
                                                        }
                                                    }
                                                    FirebaseDatabase.getInstance().getReference()
                                                            .child(DatabaseConstants.LOCATION_FRIEND_REQUEST)
                                                            .orderByChild(userId)
                                                            .equalTo(true)
                                                            .addListenerForSingleValueEvent(new ValueEventListener() {
                                                                @Override
                                                                public void onDataChange(DataSnapshot dataSnapshot) {
                                                                    if (dataSnapshot.exists()) {
                                                                        for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
                                                                            final String friendRequestId = snapshot.getKey();
                                                                            deleteUpdate.delete(new ChildLocation()
                                                                                    .child(DatabaseConstants.LOCATION_FRIEND_REQUEST)
                                                                                    .child(friendRequestId)
                                                                                    .child(userId));
                                                                        }
                                                                    }
                                                                    deleteUpdate.delete(new ChildLocation()
                                                                            .child(DatabaseConstants.LOCATION_USER_GROUPS)
                                                                            .child(userId));
                                                                    deleteUpdate.delete(new ChildLocation()
                                                                            .child(DatabaseConstants.LOCATION_GRADES)
                                                                            .child(userId));
                                                                    deleteUpdate.delete(new ChildLocation()
                                                                            .child(DatabaseConstants.LOCATION_SUBJECTS)
                                                                            .child(userId));
                                                                    deleteUpdate.delete(new ChildLocation()
                                                                            .child(DatabaseConstants.LOCATION_USER_FRIENDS)
                                                                            .child(userId));
                                                                    deleteUpdate.delete(new ChildLocation()
                                                                            .child(DatabaseConstants.LOCATION_USER_TOKENS)
                                                                            .child(userId));
                                                                    deleteUpdate.delete(new ChildLocation()
                                                                            .child(DatabaseConstants.LOCATION_USERS)
                                                                            .child(userId));
                                                                    deleteUpdate.delete(new ChildLocation()
                                                                            .child(DatabaseConstants.LOCATION_FRIEND_REQUEST)
                                                                            .child(userId));
                                                                    deleteUpdate.update(new DatabaseReference.CompletionListener() {
                                                                        @Override
                                                                        public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
                                                                            if (databaseError != null) {
                                                                                databaseError.toException().printStackTrace();
                                                                            }
                                                                        }
                                                                    });
                                                                }
                                                                @Override
                                                                public void onCancelled(DatabaseError databaseError) {
                                                                    databaseError.toException().printStackTrace();
                                                                }
                                                            });
                                                }
                                                @Override
                                                public void onCancelled(DatabaseError databaseError) {
                                                    databaseError.toException().printStackTrace();
                                                }
                                            });

                                }
                                @Override
                                public void onCancelled(DatabaseError databaseError) {
                                    databaseError.toException().printStackTrace();
                                }
                            });
                }
                @Override
                public void onCancelled(DatabaseError databaseError) {
                    databaseError.toException().printStackTrace();
                }
            });
}

As you can see, its hell to debug and maintain... I didn't include the GroupRequestManager.deleteGroup(..) but trust, its same hell as this method.. the problem is now what should I do? 如您所见,它的调试和维护工作很GroupRequestManager.deleteGroup(..) ...我没有包括GroupRequestManager.deleteGroup(..)但值得信赖,它与这种方法一样..现在的问题是我该怎么办? Is there some sort of flattening nested call framework? 是否有某种扁平化的嵌套调用框架? Its tricky, because all these calls need to be made in order to get the correct data.. What will help solve this hell? 这很棘手,因为需要进行所有这些调用才能获取正确的数据。什么能帮助解决这一难题? Another style of programing? 另一种编程风格? RxJava? RxJava? Do I switch to kotlin? 我会改用Kotlin吗? Do I just not give the user the option to delete his account, and instead just "disable" it or something? 我是否只是不让用户选择删除其帐户,而是只是“禁用”它或其他?

As Doug Stevenson said, is no worse than creating the user data at all the locations. 正如道格·史蒂文森(Doug Stevenson)所说,这不比在所有位置创建用户数据都差。 Actually is simpler. 其实比较简单。 Create a method in which set the value to null for your location like this: 创建一个方法, set the value to null您所在位置set the value to null ,如下所示:

private static void deleteUser() {
    Map<String, Object> map = new HashMap<>();
    map.put("referenceOne", new HashMap<>().put("keyOne", null));
    map.put("referenceTwo", new HashMap<>().put(keyTwo, null));
    map.put("referenceThree", new HashMap<>().put(keyThree, null));
    //and so on
    databaseReference.updateChildren(map);
}

This is the best way to do this because you'll delete all your data at once. 这是最好的方法,因为您将立即删除所有数据。 It is also called atomic transactions because in this way you'll be sure that all thise lines of code will be executed. 这也称为原子事务,因为通过这种方式,您可以确保所有此代码行都将被执行。

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM