diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java index dd191626f..f10bf7ae4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/RecipientDatabase.java @@ -812,17 +812,18 @@ public class RecipientDatabase extends Database { } } - public void applyStorageSyncUpdates(@NonNull Collection contactInserts, - @NonNull Collection> contactUpdates, - @NonNull Collection groupV1Inserts, - @NonNull Collection> groupV1Updates, - @NonNull Collection groupV2Inserts, - @NonNull Collection> groupV2Updates) + public boolean applyStorageSyncUpdates(@NonNull Collection contactInserts, + @NonNull Collection> contactUpdates, + @NonNull Collection groupV1Inserts, + @NonNull Collection> groupV1Updates, + @NonNull Collection groupV2Inserts, + @NonNull Collection> groupV2Updates) { SQLiteDatabase db = databaseHelper.getWritableDatabase(); IdentityDatabase identityDatabase = DatabaseFactory.getIdentityDatabase(context); ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); Set needsRefresh = new HashSet<>(); + boolean forcePush = false; db.beginTransaction(); @@ -944,12 +945,17 @@ public class RecipientDatabase extends Database { } for (SignalGroupV1Record insert : groupV1Inserts) { - db.insertOrThrow(TABLE_NAME, null, getValuesForStorageGroupV1(insert)); + long id = db.insertWithOnConflict(TABLE_NAME, null, getValuesForStorageGroupV1(insert), SQLiteDatabase.CONFLICT_IGNORE); - Recipient recipient = Recipient.externalGroupExact(context, GroupId.v1orThrow(insert.getGroupId())); + if (id < 0) { + Log.w(TAG, "Duplicate GV1 entry detected! Ignoring, suggesting force-push."); + forcePush = true; + } else { + Recipient recipient = Recipient.externalGroupExact(context, GroupId.v1orThrow(insert.getGroupId())); - threadDatabase.applyStorageSyncUpdate(recipient.getId(), insert); - needsRefresh.add(recipient.getId()); + threadDatabase.applyStorageSyncUpdate(recipient.getId(), insert); + needsRefresh.add(recipient.getId()); + } } for (RecordUpdate update : groupV1Updates) { @@ -1017,6 +1023,8 @@ public class RecipientDatabase extends Database { for (RecipientId id : needsRefresh) { Recipient.live(id).refresh(); } + + return forcePush; } public void applyStorageSyncUpdates(@NonNull StorageId storageId, SignalAccountRecord update) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java index 0dffad863..70f05dde1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/StorageSyncJob.java @@ -198,7 +198,7 @@ public class StorageSyncJob extends BaseJob { } migrateToGv2IfNecessary(context, mergeResult.getLocalGroupV2Inserts()); - recipientDatabase.applyStorageSyncUpdates(mergeResult.getLocalContactInserts(), mergeResult.getLocalContactUpdates(), mergeResult.getLocalGroupV1Inserts(), mergeResult.getLocalGroupV1Updates(), mergeResult.getLocalGroupV2Inserts(), mergeResult.getLocalGroupV2Updates()); + needsForcePush |= recipientDatabase.applyStorageSyncUpdates(mergeResult.getLocalContactInserts(), mergeResult.getLocalContactUpdates(), mergeResult.getLocalGroupV1Inserts(), mergeResult.getLocalGroupV1Updates(), mergeResult.getLocalGroupV2Inserts(), mergeResult.getLocalGroupV2Updates()); storageKeyDatabase.applyStorageSyncUpdates(mergeResult.getLocalUnknownInserts(), mergeResult.getLocalUnknownDeletes()); StorageSyncHelper.applyAccountStorageSyncUpdates(context, mergeResult.getLocalAccountUpdate());