@@ -16,6 +16,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Locale;
@@ -23,6 +24,7 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 import java.util.function.Consumer;
+import java.util.stream.Collectors;
 
 import io.ipfs.cid.Cid;
 
@@ -1303,6 +1305,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
                     // TODO use occupant id for isSelf assessment
                     final boolean isReceived = !mucOptions.isSelf(counterpart);
                     if (occupantId != null && message != null) {
+                        final var newReactions = new HashSet<>(reactions.getReactions());
+                        newReactions.removeAll(message.getReactions().stream().filter(r -> occupantId.equals(r.occupantId)).map(r -> r.reaction).collect(Collectors.toList()));
                         final var combinedReactions =
                                 Reaction.withOccupantId(
                                         message.getReactions(),
@@ -1314,6 +1318,7 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
                                         message.getRemoteMsgId());
                         message.setReactions(combinedReactions);
                         mXmppConnectionService.updateMessage(message, false);
+                        if (!isCarbon) mXmppConnectionService.getNotificationService().push(message, counterpart, occupantId, newReactions);
                     } else {
                         Log.d(Config.LOGTAG,"not found occupant or message");
                     }
@@ -1330,6 +1335,8 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
                     }
                     packet.fromAccount(account);
                     if (message != null) {
+                        final var newReactions = new HashSet<>(reactions.getReactions());
+                        newReactions.removeAll(message.getReactions().stream().filter(r -> reactionFrom.equals(r.from)).map(r -> r.reaction).collect(Collectors.toList()));
                         final var combinedReactions =
                                 Reaction.withFrom(
                                         message.getReactions(),
@@ -1339,6 +1346,7 @@ public class MessageParser extends AbstractParser implements Consumer<im.convers
                                         message.getRemoteMsgId());
                         message.setReactions(combinedReactions);
                         mXmppConnectionService.updateMessage(message, false);
+                        if (!isCarbon) mXmppConnectionService.getNotificationService().push(message, counterpart, null, newReactions);
                     }
                 }
             }
  
  
  
    
    @@ -64,6 +64,7 @@ import eu.siacs.conversations.entities.Contact;
 import eu.siacs.conversations.entities.Conversation;
 import eu.siacs.conversations.entities.Conversational;
 import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.entities.Reaction;
 import eu.siacs.conversations.entities.MucOptions;
 import eu.siacs.conversations.persistance.FileBackend;
 import eu.siacs.conversations.ui.ConversationsActivity;
@@ -85,6 +86,7 @@ import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.HashMap;
@@ -533,6 +535,26 @@ public class NotificationService {
         }
     }
 
+    public void push(final Message reactingTo, final Jid counterpart, final String occupantId, final Collection<String> newReactions) {
+        if (newReactions.isEmpty()) return;
+
+        final var message = reactingTo.reply();
+        message.appendBody(String.join(" ", newReactions));
+        message.setCounterpart(counterpart);
+        message.setOccupantId(occupantId);
+        message.setStatus(Message.STATUS_RECEIVED);
+        synchronized (CATCHUP_LOCK) {
+            final XmppConnection connection =
+                    message.getConversation().getAccount().getXmppConnection();
+            if (connection != null && connection.isWaitingForSmCatchup()) {
+                connection.incrementSmCatchupMessageCounter();
+                pushFromBacklog(message);
+            } else {
+                pushNow(message);
+            }
+        }
+    }
+
     public void pushFailedDelivery(final Message message) {
         final Conversation conversation = (Conversation) message.getConversation();
         final boolean isScreenLocked = !mXmppConnectionService.isScreenLocked();