let's say I want to delete an entry from the Firebase Storage and also the meta data from the Firebase Database. Should I then delete them independently from each other like this:
@Override
public void onDeleteClick(int position) {
Upload selectedItem = mUploads.get(position);
String selectedKey = selectedItem.getKey();
StorageReference imageRef = FirebaseStorage.getInstance().getReferenceFromUrl(selectedItem.getImageUrl());
imageRef.delete();
mDatabaseRef.child(selectedKey).removeValue();
}
Or should I put the database deletion part into the onSuccessListener of the storage delete method?
@Override
public void onDeleteClick(int position) {
Upload selectedItem = mUploads.get(position);
final String selectedKey = selectedItem.getKey();
StorageReference imageRef = FirebaseStorage.getInstance().getReferenceFromUrl(selectedItem.getImageUrl());
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
mDatabaseRef.child(selectedKey).removeValue();
}
});
mDatabaseRef.child(selectedKey).removeValue();
}
Whenever you need to delete an item and a reference across multiple services, you run the chance that one operation completes and the other fails. This will lead to corrupted data, so you'll need to figure out what is least harmful for your app:
- Having an orphaned image, with no database node referring to it.
- Having a database property pointing to an image that no longer exists.
If the orphaned image is the less harmful option for your app, delete the database node first and then delete the image in the completion handler. This is my preferred option, since my client application code does not need any special handling for the orphaned images.
If having a dangling reference in the database is least harmful, delete the file first and then update the database as Peter answered.
Whichever option you choose, you'll typically want to periodically run a maintenance process that cleans up the dangling references in the database, and/or the orphaned files in storage.
StorageReference imageRef = FirebaseStorage.getInstance().getReferenceFromUrl(selectedItem.getImageUrl());
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
mDatabaseRef.child(selectedKey).removeValue();
}
});
It is better to use the second way, since you know that the deletion will be successful then also delete the link of the image that is in the database.
Better than deleting from the database and maybe it did not delete from the storage, you will have a user without an image for example.