diff --git a/src/database/entities/channel.rs b/src/database/entities/channel.rs
index c1fd37becd767c2d2e6d9f973a7fcf087afaf4d6..1c7c96ae89015689c9489ea8a316dad62ac42ec6 100644
--- a/src/database/entities/channel.rs
+++ b/src/database/entities/channel.rs
@@ -106,6 +106,7 @@ impl Channel {
         ClientboundNotification::ChannelUpdate {
             id: id.clone(),
             data,
+            clear: None
         }
         .publish(id)
         .await
@@ -195,6 +196,12 @@ impl Channel {
             .publish(id.to_string())
             .await
             .ok();
+        
+        if let Channel::Group { icon, .. } = self {
+            if let Some(attachment) = icon {
+                attachment.delete().await?;
+            }
+        }
 
         Ok(())
     }
diff --git a/src/notifications/events.rs b/src/notifications/events.rs
index c67c7d1fb8a5b60569717c75eacd96f03ae692cb..9ff4cf0b8f238c50d349e89a8834b93ce767d05a 100644
--- a/src/notifications/events.rs
+++ b/src/notifications/events.rs
@@ -30,6 +30,19 @@ pub enum ServerboundNotification {
     EndTyping { channel: String },
 }
 
+#[derive(Serialize, Deserialize, Debug)]
+pub enum RemoveUserField {
+    ProfileContent,
+    ProfileBackground,
+    StatusText,
+    Avatar
+}
+
+#[derive(Serialize, Deserialize, Debug)]
+pub enum RemoveChannelField {
+    Icon
+}
+
 #[derive(Serialize, Deserialize, Debug)]
 #[serde(tag = "type")]
 pub enum ClientboundNotification {
@@ -53,6 +66,8 @@ pub enum ClientboundNotification {
     ChannelUpdate {
         id: String,
         data: JsonValue,
+        #[serde(skip_serializing_if = "Option::is_none")]
+        clear: Option<RemoveChannelField>
     },
     ChannelGroupJoin {
         id: String,
@@ -77,6 +92,8 @@ pub enum ClientboundNotification {
     UserUpdate {
         id: String,
         data: JsonValue,
+        #[serde(skip_serializing_if = "Option::is_none")]
+        clear: Option<RemoveUserField>
     },
     UserRelationship {
         id: String,
diff --git a/src/routes/channels/edit_channel.rs b/src/routes/channels/edit_channel.rs
index 4e1d971f9f9c574b8ad81552e7433885c9047309..ff5c47316ef5454ba07f3e485ee26f5403934e0e 100644
--- a/src/routes/channels/edit_channel.rs
+++ b/src/routes/channels/edit_channel.rs
@@ -1,4 +1,4 @@
-use crate::database::*;
+use crate::{database::*, notifications::events::RemoveChannelField};
 use crate::notifications::events::ClientboundNotification;
 use crate::util::result::{Error, Result};
 
@@ -17,15 +17,16 @@ pub struct Data {
     description: Option<String>,
     #[validate(length(min = 1, max = 128))]
     icon: Option<String>,
+    remove: Option<RemoveChannelField>
 }
 
-#[patch("/<target>", data = "<info>")]
-pub async fn req(user: User, target: Ref, info: Json<Data>) -> Result<()> {
-    let info = info.into_inner();
-    info.validate()
+#[patch("/<target>", data = "<data>")]
+pub async fn req(user: User, target: Ref, data: Json<Data>) -> Result<()> {
+    let data = data.into_inner();
+    data.validate()
         .map_err(|error| Error::FailedValidation { error })?;
 
-    if info.name.is_none() && info.description.is_none() && info.icon.is_none() {
+    if data.name.is_none() && data.description.is_none() && data.icon.is_none() && data.remove.is_none() {
         return Ok(());
     }
 
@@ -42,16 +43,27 @@ pub async fn req(user: User, target: Ref, info: Json<Data>) -> Result<()> {
     match &target {
         Channel::Group { id, icon, .. } => {
             let mut set = doc! {};
-            if let Some(name) = &info.name {
+            let mut unset = doc! {};
+
+            let mut remove_icon = false;
+            if let Some(remove) = &data.remove {
+                match remove {
+                    RemoveChannelField::Icon => {
+                        unset.insert("icon", 1);
+                        remove_icon = true;
+                    }
+                }
+            }
+
+            if let Some(name) = &data.name {
                 set.insert("name", name);
             }
 
-            if let Some(description) = info.description {
+            if let Some(description) = &data.description {
                 set.insert("description", description);
             }
 
-            let mut remove_icon = false;
-            if let Some(attachment_id) = info.icon {
+            if let Some(attachment_id) = &data.icon {
                 let attachment = File::find_and_use(&attachment_id, "icons", "object", &user.id).await?;
                 set.insert(
                     "icon",
@@ -64,10 +76,19 @@ pub async fn req(user: User, target: Ref, info: Json<Data>) -> Result<()> {
                 remove_icon = true;
             }
 
+            let mut operations = doc! {};
+            if set.len() > 0 {
+                operations.insert("$set", &set);
+            }
+        
+            if unset.len() > 0 {
+                operations.insert("$unset", unset);
+            }
+
             get_collection("channels")
             .update_one(
                 doc! { "_id": &id },
-                doc! { "$set": &set },
+                operations,
                 None
             )
             .await
@@ -76,12 +97,13 @@ pub async fn req(user: User, target: Ref, info: Json<Data>) -> Result<()> {
             ClientboundNotification::ChannelUpdate {
                 id: id.clone(),
                 data: json!(set),
+                clear: data.remove
             }
             .publish(id.clone())
             .await
             .ok();
 
-            if let Some(name) = info.name {
+            if let Some(name) = data.name {
                 Message::create(
                     "00000000000000000000000000".to_string(),
                     id.clone(),
diff --git a/src/routes/users/change_username.rs b/src/routes/users/change_username.rs
index 206c8eb3bf325914c765e9ebf627167986b24a90..1daa11fc129e11117bf29720bb1bd2156095f96d 100644
--- a/src/routes/users/change_username.rs
+++ b/src/routes/users/change_username.rs
@@ -58,6 +58,7 @@ pub async fn req(
     ClientboundNotification::UserUpdate {
         id: user.id.clone(),
         data: json!(data.0),
+        clear: None
     }
     .publish(user.id.clone())
     .await
diff --git a/src/routes/users/edit_user.rs b/src/routes/users/edit_user.rs
index ee5db9177f5af7ab5140f9fa061b8cfc61e2014b..f240a579bbbb7b32f119b25fa721251c6ecb940a 100644
--- a/src/routes/users/edit_user.rs
+++ b/src/routes/users/edit_user.rs
@@ -1,4 +1,4 @@
-use crate::database::*;
+use crate::{database::*, notifications::events::RemoveUserField};
 use crate::notifications::events::ClientboundNotification;
 use crate::util::result::{Error, Result};
 
@@ -17,14 +17,6 @@ pub struct UserProfileData {
     background: Option<String>,
 }
 
-#[derive(Serialize, Deserialize)]
-pub enum RemoveField {
-    ProfileContent,
-    ProfileBackground,
-    StatusText,
-    Avatar
-}
-
 #[derive(Validate, Serialize, Deserialize)]
 pub struct Data {
     #[validate]
@@ -33,15 +25,12 @@ pub struct Data {
     profile: Option<UserProfileData>,
     #[validate(length(min = 1, max = 128))]
     avatar: Option<String>,
-    remove: Option<RemoveField>
+    remove: Option<RemoveUserField>
 }
 
 #[patch("/<_ignore_id>", data = "<data>")]
 pub async fn req(user: User, data: Json<Data>, _ignore_id: String) -> Result<()> {
     let mut data = data.into_inner();
-    if data.status.is_none() && data.profile.is_none() && data.avatar.is_none() {
-        return Ok(());
-    }
 
     data.validate()
         .map_err(|error| Error::FailedValidation { error })?;
@@ -52,19 +41,19 @@ pub async fn req(user: User, data: Json<Data>, _ignore_id: String) -> Result<()>
     let mut remove_background = false;
     let mut remove_avatar = false;
 
-    if let Some(remove) = data.remove {
+    if let Some(remove) = &data.remove {
         match remove {
-            RemoveField::ProfileContent => {
+            RemoveUserField::ProfileContent => {
                 unset.insert("profile.content", 1);
             },
-            RemoveField::ProfileBackground => {
+            RemoveUserField::ProfileBackground => {
                 unset.insert("profile.background", 1);
                 remove_background = true;
             }
-            RemoveField::StatusText => {
+            RemoveUserField::StatusText => {
                 unset.insert("status.text", 1);
             },
-            RemoveField::Avatar => {
+            RemoveUserField::Avatar => {
                 unset.insert("avatar", 1);
                 remove_avatar = true;
             }
@@ -117,18 +106,28 @@ pub async fn req(user: User, data: Json<Data>, _ignore_id: String) -> Result<()>
         None
     };
 
+    let mut operations = doc! {};
+    if set.len() > 0 {
+        operations.insert("$set", set);
+    }
+
+    if unset.len() > 0 {
+        operations.insert("$unset", unset);
+    }
+
     get_collection("users")
-        .update_one(doc! { "_id": &user.id }, doc! { "$set": set }, None)
+        .update_one(doc! { "_id": &user.id }, operations, None)
         .await
         .map_err(|_| Error::DatabaseError {
             operation: "update_one",
             with: "user",
         })?;
 
-    if let Some(status) = data.status {
+    if let Some(status) = &data.status {
         ClientboundNotification::UserUpdate {
             id: user.id.clone(),
             data: json!({ "status": status }),
+            clear: None
         }
         .publish(user.id.clone())
         .await
@@ -139,6 +138,18 @@ pub async fn req(user: User, data: Json<Data>, _ignore_id: String) -> Result<()>
         ClientboundNotification::UserUpdate {
             id: user.id.clone(),
             data: json!({ "avatar": avatar }),
+            clear: None
+        }
+        .publish(user.id.clone())
+        .await
+        .ok();
+    }
+
+    if let Some(clear) = data.remove {
+        ClientboundNotification::UserUpdate {
+            id: user.id.clone(),
+            data: json!({}),
+            clear: Some(clear)
         }
         .publish(user.id.clone())
         .await