问题
I'm still on Firebase and this time I have a question related on the deletion of objects.
I have a structure like the following:
users: {
UsErId1:{
name: "Jack",
email: "m@i.l"
},
UsErId2: { + },
UsErId3: { + }
},
user_contacts: {
UsErId1:{
UsErId2: true,
UsErId3: true
},
UsErId2: {
UsErId1: true
}
}
So if I want to delete an user I have to:
- Delete the user object
- Delete the user object under the user_contacts branch
- Remove all the indexes from user_contacts that are pointing to that user
My performance problems comes from the point 3, because I need to iterate all the user_contacts entries to see if a user it's present in the childrens.
An example of code is the following:
private void deleteUser(String userId) {
firebaseDatabase.getReference("users").child(userId).removeValue();
firebaseDatabase.getReference("users_contacts").child(userId).removeValue();
firebaseDatabase.getReference("users_contacts").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot usersSnapshot : dataSnapshot.getChildren()) {
for( DataSnapshot contactSnapshot : usersSnapshot.getChildren() ){
String contactId = contactSnapshot.getValue(String.class);
if( contactId.equals(userId) ){
contactSnapshot.getRef().removeValue();
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
I've thought of two possible solutions:
Solution 1: Don't delete the indexes from
user_contacts
and when I've to load the user contacts, I've to do a call to each user to see if the user is null (has been deleted), and in that case, don't show it. By the way, this results in a dirty database.Solution 2: create a reverse index
contacts_users
where I store the users for which the user I'm trying to delete is referenced. As follow:contacts_user: { UsErId1: { UsErId2: true }, UsErId2: { UsErId1: true }, UsErId3: { UsErId1: true } }
So, when I have to delete a user, I will look at its childs in contacts_users
and know every users that has it in its contacts, and proceed to delete it (now that I can know the entire path). This seems to me to be a more NoSql-like approach.
What do you think? Is there another way to do it?
回答1:
Your second solution is how I would suggest doing it, no need to search. You could store that information on a per user basis, but if it grows too large having it elsewhere is better.
Likewise deleting in the other direction also becomes easier.
来源:https://stackoverflow.com/questions/39850117/remove-indexes-that-are-in-nested-field-when-deleting-an-object