Skip to content

feat: opt-in sync of deletes and restores from web to Android#16732

Merged
alextran1502 merged 30 commits intoimmich-app:mainfrom
aleksandrsovtan:mobile/manage_local_media_files
Apr 8, 2025
Merged

feat: opt-in sync of deletes and restores from web to Android#16732
alextran1502 merged 30 commits intoimmich-app:mainfrom
aleksandrsovtan:mobile/manage_local_media_files

Conversation

@aleksandrsovtan
Copy link
Copy Markdown
Contributor

Description

Functionality for synchronizing the local media store when remotely deleting to trash and restoring files has been added. (Android)
This solves the issue of file deletion synchronization on web and mobile apps.

Fixes # (issue)

How Has This Been Tested?

To verify this, you need an Android 11+ device.

  1. Launch the Flutter app on an Android device.
  2. Log in to the app (I used the demo server and demo account).
  3. Go to Settings => Advanced and enable the 'Sync remote deletions' switch.
  4. Download any photo or multiple photos from the photo list.
  5. Grant access to local albums, specifically to the Immich album (Cloud icon to the left of the profile icon).
  6. Open the Immich web app and log in with the same account (I used the demo).
  7. In the web app, delete (move to trash) a photo that is locally downloaded on your phone (marked with a cloud + icon).
  8. Open the gallery, go to the trash, and you should see the file that is in the trash on the web app.
  9. Return to the mobile app.
  10. In the web app, restore the file from the trash, and make sure it appears in the Flutter app's photo list (with the cloud + icon).
  11. Open the gallery, and the file should be in the Immich folder (restored).

Checklist:

  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation if applicable
  • I have no unrelated changes in the PR.
  • I have confirmed that any new dependencies are strictly necessary.
  • I have written tests for new code (if applicable)
  • I have followed naming conventions/patterns in the surrounding code
  • All code in src/services/ uses repositories implementations for database calls, filesystem operations, etc.
  • All code in src/repositories/ is pretty basic/simple and does not have any immich specific logic (that belongs in src/services/)

@benmccann benmccann changed the title Features: Local file movement to trash and restoration back to the album added. (Android) feat: opt-in sync of deletes and restored from web to Android Mar 8, 2025
@benmccann benmccann changed the title feat: opt-in sync of deletes and restored from web to Android feat: opt-in sync of deletes and restores from web to Android Mar 8, 2025
SettingsSwitchListTile(
enabled: true,
valueNotifier: manageLocalMediaAndroid,
title: "Sync remote deletions",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please put the string to en-us.json

suggestion for the subtitle string

Automatically delete or restore an asset on this device when that action is taken on the web

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I would like to mark this as [EXPERIMENTAL]

@alextran1502
Copy link
Copy Markdown
Member

Hello, I just ran the first round of functional testing on a Samsung S23, and I don't see the behavior I expected. Let me know if I misunderstood the PR's functionality.

  1. Make sure that the option is enabled
  2. Make sure the target asset is synced and present on the local device, meaning cloud + check icon.
  3. Go to the web and trash the asset, confirm that the asset is in the trash
  4. In the mobile app, I can see that the asset is in Immich's trash
  5. I checked the native file explorer; in this case, it is the Samsung "My File" app. I checked the trash page, but I don't see any trash file there.

Let me know if I have tested the PR correctly.

title: "advanced_settings_troubleshooting_title".tr(),
subtitle: "advanced_settings_troubleshooting_subtitle".tr(),
),
SettingsSwitchListTile(
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should only show on Android

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You tested it a bit incorrectly. The Media Store API works with media files that are located in the gallery. So, after deletion, we need to check the trash in the gallery, not the trash in the file manager.

When deleting a downloaded file in the web app, the file moves from the album to the trash (gallery), and when restoring it in the web app, it returns to the album from the trash.

Copy link
Copy Markdown
Member

@shenlong-tanwen shenlong-tanwen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it is a good idea to try to keep the Trash inside Immich to be in sync with the one on the device. We can configure the number of days after which an asset is permanently deleted from the trash in Immich. However, the System trash on the device defaults to a 30 days window, after which the asset is removed permanently from the device. If the trash days is >30 inside Immich and the user tries to restore the asset after 30 days, there will be no asset, anymore on the device to be restored. It is not a problem with the other app because it defaults to having 30 days as the trash window.

Comment thread mobile/lib/services/sync.service.dart Outdated
Comment thread mobile/lib/services/sync.service.dart Outdated
@benmccann
Copy link
Copy Markdown
Collaborator

I'm not sure it is a good idea to try to keep the Trash inside Immich to be in sync with the one on the device. We can configure the number of days after which an asset is permanently deleted from the trash in Immich. However, the System trash on the device defaults to a 30 days window, after which the asset is removed permanently from the device.

This is a good catch. I do think it's kind of nice that it's viewable in the system trash though. I think there are a few options here:

  • Immich does not use system trash and has its own trash
  • Immich removes ability to configure trash length and uses 30 days like Android and iOS
  • The photo is deleted on the mobile device at 30 days or Immich configured date - whichever is soonest. The image would probably be restorable from the server if it has a longer retention period
  • Same as the last option, but also cap the Immich retention at 30 days so the values do not conflict

Do you have an opinion @alextran1502 ?

@alextran1502
Copy link
Copy Markdown
Member

Immich removes ability to configure trash length and uses 30 days like Android and iOS

I think this is the best compromise. The default is always to trash and have 30 days before deletion.

@jrasm91 any thoughts about this?

@jrasm91
Copy link
Copy Markdown
Member

jrasm91 commented Mar 14, 2025

Personally, I think if you trash a file in Immich with this option enabled:

  • The web should show a message similar to google photos
  • The mobile app moves it to system trash
  • The server deletes it after the configured trash days
  • The mobile operating system deletes it following the system trash policy

Specifically when the Immich's trash policy in longer than 30 days I think it's fine for the item to be deleted on the device and only be restored on the web.

When the Immich trash policy is shorter than 30 days, I think it's also fine to leave the trashed photo in the mobile trash.

image

@benmccann
Copy link
Copy Markdown
Collaborator

I think that's probably pretty close to what happens with this PR today. I guess my question would be what happens if an asset is deleted from one trash and then restored from the other? Will it get synced to the other device? How and when does that happen? I think what Alex suggested is simpler conceptually in that it avoids cases like that.

It's been hard to keep this PR in sync with main and it keeps falling down the queue, so I sort of wonder if we shouldn't just merge it as is and figure out any follow ups separately.

Comment thread mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt Outdated
@aleksandrsovtan
Copy link
Copy Markdown
Contributor Author

@aleksandrsovtan I just tested the permission logic and saw the following behaviors

  • Upon toggling the feature from the Immich app, the native permission prompt is presented as expected; however, when the user does not gain file access permission and returns to the app, the feature is still being turned on. I expect that if the user denies the permission, the feature will stay off.
  • If the file access permission is gained, toggling the feature should not show the native permission prompt again. The native prompt is shown each time the feature switches from off -> on.

Can you help me resolve those two issues? We are very close now! 😃

@alextran1502 done!)

@alextran1502 alextran1502 merged commit 2b131fe into immich-app:main Apr 8, 2025
39 checks passed
alextran1502 added a commit that referenced this pull request Apr 23, 2025
alextran1502 added a commit that referenced this pull request Apr 23, 2025
* chore: revert #16732

* lint
@BWagener
Copy link
Copy Markdown

I really hope there is a solution for the permission problem with the playstore.

Is there already an issue for this? Or is this the place to discuss it?

@shenlong-tanwen
Copy link
Copy Markdown
Member

I really hope there is a solution for the permission problem with the playstore.

We are in the process of adding it back using a less intrusive permission on Android - #17828.

@cchristchurch
Copy link
Copy Markdown

I have updated both the android app and the server to 1.132.3, however I still cannot see the experimental setting "Sync remote deletions" in the "Advanced" settings section. What am I missing?

Note that my phone is still running Android 11, could that be the reason?

savely-krasovsky pushed a commit to savely-krasovsky/immich that referenced this pull request Jun 8, 2025
…-app#16732)

* Features: Local file movement to trash and restoration back to the album added. (Android)

* Comments fixes

* settings button marked as [EXPERIMENTAL]

* _moveToTrashMatchedAssets refactored, moveToTrash renamed.

* fix: bad merge

* Permission check and request for local storage added.

* Permission request added on settings switcher

* Settings button logic changed

* Method channel file_trash moved to BackgroundServicePlugin

---------

Co-authored-by: Alex <alex.tran1502@gmail.com>
savely-krasovsky pushed a commit to savely-krasovsky/immich that referenced this pull request Jun 8, 2025
@kujlek
Copy link
Copy Markdown

kujlek commented Feb 6, 2026

I still have issues with deleted files on my local server. When I delete photos on immich web page, the photos are deleted on disk after emptying the trash. But after a while (on next client-server sync) they are uploaded again from the mobile phone app even though I have the "Sync remote deletions" turned on.

Server version 2.5.3 (using storage templates)
Android client version 2.5.3

@PeterOmbodi
Copy link
Copy Markdown
Contributor

PeterOmbodi commented Feb 9, 2026

@kujlek Did I understand correctly that between deleting the assets and emptying the trash you do not use the mobile app, meaning the client–server sync does not have a chance to run?
If so, could you please try triggering a sync on the mobile device before emptying the remote trash (for example, by backgrounding and reopening the app) and let us know here whether this changes the behavior?
Is backup enabled on your mobile device, and is the album containing the affected assets included in the backup list?

Deeds67 added a commit to open-noodle/gallery that referenced this pull request Mar 12, 2026
Add details about existing Android opt-in trash sync (upstream PRs immich-app#16732,
immich-app#20473, immich-app#24218) and potential future improvements (iOS support, push-based sync,
mobile→web delete direction).
Deeds67 added a commit to open-noodle/gallery that referenced this pull request Mar 12, 2026
* docs: add Google Photos import wizard design

Web UI wizard for importing Google Takeout exports. Client-side hybrid
approach: browser streams zips, parses JSON sidecars, shows preview with
album selection, uploads through existing asset API. 5-step wizard with
source selection, file picker, scanning, review/configure, and import
progress. TDD required for all implementation.

* docs: add Google Photos import implementation plan (18 TDD tasks)

* docs: update delete sync feature notes with implementation status

Add details about existing Android opt-in trash sync (upstream PRs immich-app#16732,
immich-app#20473, immich-app#24218) and potential future improvements (iOS support, push-based sync,
mobile→web delete direction).

* feat: auto-publish Docker images on PR merge with semver bumping

Enable push trigger on main so every merged PR automatically builds and
publishes Docker images. Version is computed from the latest git tag:

- changelog:feat label or feat: prefix → minor bump
- BREAKING CHANGE in body → major bump
- everything else → patch bump

Manual workflow_dispatch with explicit version still supported as override.
A tag job creates the git tag after successful builds.

* fix: format docs plan files for prettier check

* docs: update README with v3.0.0 and auto-publish details

* fix: resolve zizmor security findings in Docker workflow

- Pass inputs.version through env var instead of template expansion in run blocks
- Pass version output through env var for tag creation step
- Add persist-credentials: true explicitly on tag job checkout (needs push access)
@kujlek
Copy link
Copy Markdown

kujlek commented Apr 3, 2026

Hi, I've managed to reproduce the issue with latest immich server v2.6.3 and android app v2.6.3.

Web UI delete works ok (images are not re-uploaded) if these steps are taken:

  • move images to trash
  • sync immich app on phone
  • empty the trash
  • sync immich app on phone

Images are re-uploaded if immich app sync is not done between moving image to trash and emptying it.

@PeterOmbodi
Copy link
Copy Markdown
Contributor

@kujlek The fix for the scenario you described has already been implemented in PR #26070. Although it has been approved, it unfortunately has not been merged yet.
Once a release including this fix is available, it would be great if you could re-test your flow with opt-in sync of deletes enabled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants