diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java
index 161d3a3d1edea7609f9f9b1b1ef0f5284129ad97..4aa0cf24c0f1a80a871785682093629eda6899a4 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalBaseIdentityKeyStore.java
@@ -71,13 +71,13 @@ public class SignalBaseIdentityKeyStore {
       RecipientId         recipientId    = RecipientId.fromExternalPush(address.getName());
 
       if (identityRecord == null) {
-        Log.i(TAG, "Saving new identity...");
+        Log.i(TAG, "Saving new identity for " + address);
         cache.save(address.getName(), recipientId, identityKey, VerifiedStatus.DEFAULT, true, System.currentTimeMillis(), nonBlockingApproval);
         return SaveResult.NEW;
       }
 
       if (!identityRecord.getIdentityKey().equals(identityKey)) {
-        Log.i(TAG, "Replacing existing identity... Existing: " + identityRecord.getIdentityKey().hashCode() + " New: " + identityKey.hashCode());
+        Log.i(TAG, "Replacing existing identity for " + address + " | Existing: " + identityRecord.getIdentityKey().hashCode() + ", New: " + identityKey.hashCode());
         VerifiedStatus verifiedStatus;
 
         if (identityRecord.getVerifiedStatus() == VerifiedStatus.VERIFIED ||
@@ -96,7 +96,7 @@ public class SignalBaseIdentityKeyStore {
       }
 
       if (isNonBlockingApprovalRequired(identityRecord)) {
-        Log.i(TAG, "Setting approval status...");
+        Log.i(TAG, "Setting approval status for " + address);
         cache.setApproval(address.getName(), recipientId, identityRecord, nonBlockingApproval);
         return SaveResult.NON_BLOCKING_APPROVAL_REQUIRED;
       }
diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java
index d6bec856c89a3bfdc0f1153043fcf96d7c25a04f..1ee2571728d847a7b31507dbbed55d386723322b 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/database/IdentityDatabase.java
@@ -32,6 +32,7 @@ import org.thoughtcrime.securesms.database.model.IdentityStoreRecord;
 import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
 import org.thoughtcrime.securesms.recipients.Recipient;
 import org.thoughtcrime.securesms.recipients.RecipientId;
+import org.thoughtcrime.securesms.storage.StorageSyncHelper;
 import org.thoughtcrime.securesms.util.Base64;
 import org.signal.core.util.CursorUtil;
 import org.thoughtcrime.securesms.util.IdentityUtil;
@@ -141,6 +142,7 @@ public class IdentityDatabase extends Database {
   {
     saveIdentityInternal(addressName, recipientId, identityKey, verifiedStatus, firstUse, timestamp, nonBlockingApproval);
     SignalDatabase.recipients().markNeedsSync(recipientId);
+    StorageSyncHelper.scheduleSyncForDataChange();
   }
 
   public void setApproval(@NonNull String addressName, @NonNull RecipientId recipientId, boolean nonBlockingApproval) {
@@ -152,6 +154,7 @@ public class IdentityDatabase extends Database {
     database.update(TABLE_NAME, contentValues, ADDRESS + " = ?", SqlUtil.buildArgs(addressName));
 
     SignalDatabase.recipients().markNeedsSync(recipientId);
+    StorageSyncHelper.scheduleSyncForDataChange();
   }
 
   public void setVerified(@NonNull String addressName, @NonNull RecipientId recipientId, IdentityKey identityKey, VerifiedStatus verifiedStatus) {
@@ -169,11 +172,14 @@ public class IdentityDatabase extends Database {
       Optional<IdentityRecord> record = getIdentityRecord(addressName);
       if (record.isPresent()) EventBus.getDefault().post(record.get());
       SignalDatabase.recipients().markNeedsSync(recipientId);
+      StorageSyncHelper.scheduleSyncForDataChange();
     }
   }
 
   public void updateIdentityAfterSync(@NonNull String addressName, @NonNull RecipientId recipientId, IdentityKey identityKey, VerifiedStatus verifiedStatus) {
-    boolean hadEntry      = getIdentityRecord(addressName).isPresent();
+    Optional<IdentityRecord> existingRecord = getIdentityRecord(addressName);
+
+    boolean hadEntry      = existingRecord.isPresent();
     boolean keyMatches    = hasMatchingKey(addressName, identityKey);
     boolean statusMatches = keyMatches && hasMatchingStatus(addressName, identityKey, verifiedStatus);
 
@@ -190,7 +196,8 @@ public class IdentityDatabase extends Database {
     }
 
     if (hadEntry && !keyMatches) {
-      IdentityUtil.markIdentityUpdate(context, RecipientId.fromExternalPush(addressName));
+      Log.w(TAG, "Updated identity key during storage sync for " + addressName + " | Existing: " + existingRecord.get().getIdentityKey().hashCode() + ", New: " + identityKey.hashCode());
+      IdentityUtil.markIdentityUpdate(context, recipientId);
     }
   }
 
diff --git a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java
index 1f4dd3ea411567b02e0840a676691d017531d464..214f20c1ca28c4c7da3ebfc07aa4794d1120922a 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/storage/ContactRecordProcessor.java
@@ -86,6 +86,7 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
                        .map(r -> r.getContact().get());
   }
 
+  @Override
   @NonNull SignalContactRecord merge(@NonNull SignalContactRecord remote, @NonNull SignalContactRecord local, @NonNull StorageKeyGenerator keyGenerator) {
     String givenName;
     String familyName;
@@ -98,14 +99,25 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
       familyName = local.getFamilyName().orElse("");
     }
 
+    IdentityState identityState;
+    byte[]        identityKey;
+
+    if ((remote.getIdentityState() != local.getIdentityState() && remote.getIdentityKey().isPresent()) ||
+        (remote.getIdentityKey().isPresent() && !local.getIdentityKey().isPresent()))
+    {
+      identityState = remote.getIdentityState();
+      identityKey   = remote.getIdentityKey().get();
+    } else {
+      identityState = local.getIdentityState();
+      identityKey   = local.getIdentityKey().orElse(null);
+    }
+
     byte[]               unknownFields  = remote.serializeUnknownFields();
     ServiceId            serviceId      = local.getAddress().getServiceId() == ServiceId.UNKNOWN ? remote.getAddress().getServiceId() : local.getAddress().getServiceId();
     String               e164           = OptionalUtil.or(remote.getAddress().getNumber(), local.getAddress().getNumber()).orElse(null);
     SignalServiceAddress address        = new SignalServiceAddress(serviceId, e164);
     byte[]               profileKey     = OptionalUtil.or(remote.getProfileKey(), local.getProfileKey()).orElse(null);
     String               username       = OptionalUtil.or(remote.getUsername(), local.getUsername()).orElse("");
-    IdentityState        identityState  = remote.getIdentityKey().isPresent() ? remote.getIdentityState() : local.getIdentityState();
-    byte[]               identityKey    = OptionalUtil.or(remote.getIdentityKey(), local.getIdentityKey()).orElse(null);
     boolean              blocked        = remote.isBlocked();
     boolean              profileSharing = remote.isProfileSharingEnabled();
     boolean              archived       = remote.isArchived();
diff --git a/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java b/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java
index f62c51f69a7f2556bdfafff3497eed83338ffb42..a2b789b04510cdb90b0898f8351cdb775b33e04c 100644
--- a/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java
+++ b/app/src/main/java/org/thoughtcrime/securesms/util/IdentityUtil.java
@@ -116,6 +116,8 @@ public final class IdentityUtil {
   }
 
   public static void markIdentityUpdate(@NonNull Context context, @NonNull RecipientId recipientId) {
+    Log.w(TAG, "Inserting safety number change event(s) for " + recipientId, new Throwable());
+
     long            time          = System.currentTimeMillis();
     MessageDatabase smsDatabase   = SignalDatabase.sms();
     GroupDatabase   groupDatabase = SignalDatabase.groups();