[TECH-DEBT] Mobile upload refactor #886

Closed
opened 2026-02-04 23:19:35 +03:00 by OVERLORD · 29 comments
Owner

Originally created by @alextran1502 on GitHub (May 25, 2023).

Originally assigned to: @alextran1502 on GitHub.

Now that the support for client-side hashing has been merged into the server.

It is time to look at some long-standing issues with uploading assets from the mobile app that have been reported, such as

  • Negative remainder count.
  • Client-side hashing on the mobile app to check duplicates before uploading.
  • Better error handling on a failed upload
  • Some mobile devices cannot scan for album

The plan is to refactor the uploading code to make it cleaner as well as include new hashing and error handling mechanism

Originally created by @alextran1502 on GitHub (May 25, 2023). Originally assigned to: @alextran1502 on GitHub. Now that the support for client-side hashing has been merged into the server. It is time to look at some long-standing issues with uploading assets from the mobile app that have been reported, such as - [x] Negative remainder count. - [ ] Client-side hashing on the mobile app to check duplicates before uploading. - [ ] Better error handling on a failed upload - [x] Some mobile devices cannot scan for album The plan is to refactor the uploading code to make it cleaner as well as include new hashing and error handling mechanism
OVERLORD added the 📱mobiletech-debt labels 2026-02-04 23:19:35 +03:00
Author
Owner

@Dental1347 commented on GitHub (May 26, 2023):

May I add some things? I don't know if they're in scope of this issue:

  1. Files getting stuck in the upload queue. Restart of the app will prompt to re-upload the file (even on cellular network)
  2. Backup starts even when on cellular network.
  3. Scanning for assets sometimes takes multiple hours, seemingly doing nothing.
    If it is not, feel free to ignore my suggestions.
@Dental1347 commented on GitHub (May 26, 2023): May I add some things? I don't know if they're in scope of this issue: 1. Files getting stuck in the upload queue. Restart of the app will prompt to re-upload the file (even on cellular network) 2. Backup starts even when on cellular network. 3. Scanning for assets sometimes takes multiple hours, seemingly doing nothing. If it is not, feel free to ignore my suggestions.
Author
Owner

@Sherlock1979 commented on GitHub (May 29, 2023):

I have experienced number 3 several times.

@Sherlock1979 commented on GitHub (May 29, 2023): I have experienced number 3 several times.
Author
Owner

@Vcele commented on GitHub (May 29, 2023):

I would also love to see two way sync, so that if I delete a photo on the web it also gets removed on my phone. Maybe one could implement an out of sync warning like GPhotos does 😁

@Vcele commented on GitHub (May 29, 2023): I would also love to see two way sync, so that if I delete a photo on the web it also gets removed on my phone. Maybe one could implement an out of sync warning like GPhotos does 😁
Author
Owner

@alextran1502 commented on GitHub (May 29, 2023):

@Vcele That would be a separate feature which we will implement in the future

@alextran1502 commented on GitHub (May 29, 2023): @Vcele That would be a separate feature which we will implement in the future
Author
Owner

@phrodide commented on GitHub (May 31, 2023):

May I add some things? I don't know if they're in scope of this issue:

  1. Files getting stuck in the upload queue. Restart of the app will prompt to re-upload the file (even on cellular network)
  2. Backup starts even when on cellular network.
  3. Scanning for assets sometimes takes multiple hours, seemingly doing nothing.
    If it is not, feel free to ignore my suggestions.

it seems #1 is linked to file size. 1GB or more is suspect.

@phrodide commented on GitHub (May 31, 2023): > May I add some things? I don't know if they're in scope of this issue: > > 1. Files getting stuck in the upload queue. Restart of the app will prompt to re-upload the file (even on cellular network) > 2. Backup starts even when on cellular network. > 3. Scanning for assets sometimes takes multiple hours, seemingly doing nothing. > If it is not, feel free to ignore my suggestions. it seems #1 is linked to file size. 1GB or more is suspect.
Author
Owner

@Dental1347 commented on GitHub (Jun 1, 2023):

I just came across something which I orignally never thought of. I myself don't have this, but my direct family does. They have albums on their phones which span over multiple years. It is currently absolutely impossible to add all these pictures manually to the album that has to be manually created within immich. The photos cross around many years. If, the albums were directly created on upload and the the assets automatically added (Also future assets for that album), that would make immich so incredibly powerful for mobile backups.

Originated from general discussion within discord.

@Dental1347 commented on GitHub (Jun 1, 2023): I just came across something which I orignally never thought of. I myself don't have this, but my direct family does. They have albums on their phones which span over multiple years. It is currently absolutely impossible to add all these pictures manually to the album that has to be manually created within immich. The photos cross around many years. If, the albums were directly created on upload and the the assets automatically added (Also future assets for that album), that would make immich so incredibly powerful for mobile backups. Originated from general discussion within discord.
Author
Owner

@chriexpe commented on GitHub (Jun 21, 2023):

I just wanted to add another thing, to attach a tag to the photo with the name of the album/folder it came from, so you could later create a album or filter out just the pictures that you took (DCIM>Camera) or screenshots (DCIM>Screenshots).

@chriexpe commented on GitHub (Jun 21, 2023): I just wanted to add another thing, to attach a tag to the photo with the name of the album/folder it came from, so you could later create a album or filter out just the pictures that you took (DCIM>Camera) or screenshots (DCIM>Screenshots).
Author
Owner

@jeverling commented on GitHub (Jul 11, 2023):

I would also love to see two way sync, so that if I delete a photo on the web it also gets removed on my phone. Maybe one could implement an out of sync warning like GPhotos does grin

Please make this feature optional 🙃

@jeverling commented on GitHub (Jul 11, 2023): > I would also love to see two way sync, so that if I delete a photo on the web it also gets removed on my phone. Maybe one could implement an out of sync warning like GPhotos does grin Please make this feature optional :upside_down_face:
Author
Owner

@codeinabox commented on GitHub (Aug 4, 2023):

I too have experienced the negative counter, is there any way to fix it? As it's negative, it's unclear if any photos still need to be backed up or not

@codeinabox commented on GitHub (Aug 4, 2023): I too have experienced the negative counter, is there any way to fix it? As it's negative, it's unclear if any photos still need to be backed up or not
Author
Owner

@alextran1502 commented on GitHub (Aug 4, 2023):

@codeinabox you can fix it by either clear the app cache or reinstall the app

@alextran1502 commented on GitHub (Aug 4, 2023): @codeinabox you can fix it by either clear the app cache or reinstall the app
Author
Owner

@yurividal commented on GitHub (Oct 30, 2023):

Please consider option to pause a current upload. This is useful when the user is in an area with low cell coverage, and takes a video.
I had barely any service, and shot a video.
Immich kept trying to upload that video for hours, consuming all of the little bandwidth i had.

@yurividal commented on GitHub (Oct 30, 2023): Please consider option to pause a current upload. This is useful when the user is in an area with low cell coverage, and takes a video. I had barely any service, and shot a video. Immich kept trying to upload that video for hours, consuming all of the little bandwidth i had.
Author
Owner

@alexchomiak commented on GitHub (Jan 29, 2024):

Peeking in :) ( I love this project )

These features would be amazing, and is the only thing stopping me from downloading Immich on all of my devices at the moment.

Downloading Immich on multiple IOS devices leads to the entire library having to be re-synced. (even though duplicates aren't created. Waiting on the full file uploads for a MD5 Hash check is killing a ton of time)

With the recent launch of external libraries, this would be amazing for quickly syncing iCloud. (as I recently corrupted my Immich Postgres database & have had to resync my app. (leading to the same upload/hash check loop)

Update: This is probably a better issue for me to track on my end:
https://github.com/orgs/immich-app/projects/1/views/1?pane=issue&itemId=29492098

@alexchomiak commented on GitHub (Jan 29, 2024): Peeking in :) ( I love this project ) These features would be amazing, and is the only thing stopping me from downloading Immich on all of my devices at the moment. Downloading Immich on multiple IOS devices leads to the entire library having to be re-synced. (even though duplicates aren't created. Waiting on the full file uploads for a MD5 Hash check is killing a ton of time) With the recent launch of external libraries, this would be amazing for quickly syncing iCloud. (as I recently corrupted my Immich Postgres database & have had to resync my app. (leading to the same upload/hash check loop) Update: This is probably a better issue for me to track on my end: https://github.com/orgs/immich-app/projects/1/views/1?pane=issue&itemId=29492098
Author
Owner

@SandiyosDev commented on GitHub (Apr 14, 2024):

Peeking in :) ( I love this project )

These features would be amazing, and is the only thing stopping me from downloading Immich on all of my devices at the moment.

Downloading Immich on multiple IOS devices leads to the entire library having to be re-synced. (even though duplicates aren't created. Waiting on the full file uploads for a MD5 Hash check is killing a ton of time)

With the recent launch of external libraries, this would be amazing for quickly syncing iCloud. (as I recently corrupted my Immich Postgres database & have had to resync my app. (leading to the same upload/hash check loop)

Update: This is probably a better issue for me to track on my end: https://github.com/orgs/immich-app/projects/1/views/1?pane=issue&itemId=29492098

@alexchomiak You can indeed sync iCloud by binding the photo.photolibrary-Originals folder as a read-only external library in Immich, enable the watcher and it will sync automatically, though some exif-less photo's creation date will be wrong because its based on the date its synced from icloud, and not its original capture date.

@SandiyosDev commented on GitHub (Apr 14, 2024): > Peeking in :) ( I love this project ) > > These features would be amazing, and is the only thing stopping me from downloading Immich on all of my devices at the moment. > > Downloading Immich on multiple IOS devices leads to the entire library having to be re-synced. (even though duplicates aren't created. Waiting on the full file uploads for a MD5 Hash check is killing a ton of time) > > With the recent launch of external libraries, this would be amazing for quickly syncing iCloud. (as I recently corrupted my Immich Postgres database & have had to resync my app. (leading to the same upload/hash check loop) > > Update: This is probably a better issue for me to track on my end: https://github.com/orgs/immich-app/projects/1/views/1?pane=issue&itemId=29492098 @alexchomiak You can indeed sync iCloud by binding the photo.photolibrary-Originals folder as a read-only external library in Immich, enable the watcher and it will sync automatically, though some exif-less photo's creation date will be wrong because its based on the date its synced from icloud, and not its original capture date.
Author
Owner

@Serinus1 commented on GitHub (Jun 7, 2024):

consuming all of the little bandwidth i had.

Like whe ln you're in a tourism area taking pictures? Yes, a snooze or pause button the notification would be very nice. This could be a separate issue.

Posting live from use case #jungfrau

@Serinus1 commented on GitHub (Jun 7, 2024): >consuming all of the little bandwidth i had. Like whe ln you're in a tourism area taking pictures? Yes, a snooze or pause button the notification would be very nice. This could be a separate issue. Posting live from use case #jungfrau
Author
Owner

@TobiPeterG commented on GitHub (Jun 22, 2024):

Hey there, I'm not sure if this issue has already been reported, at least I didn't find a similar issue.
On my Android phone, the synchronization doesn't seem to work properly. For about 2 weeks, my phone has been trying to sync my photos and Videos (I didn't take any new) and the counter of to be synced Videos sometimes increases, but stays at around 624.
Also, it seems that the app continues to sync with mobile data, even though this option is disabled (the app used 9GB of mobile data this month lol)

Are you aware of these issues? Do you need any additional information?

@TobiPeterG commented on GitHub (Jun 22, 2024): Hey there, I'm not sure if this issue has already been reported, at least I didn't find a similar issue. On my Android phone, the synchronization doesn't seem to work properly. For about 2 weeks, my phone has been trying to sync my photos and Videos (I didn't take any new) and the counter of to be synced Videos sometimes increases, but stays at around 624. Also, it seems that the app continues to sync with mobile data, even though this option is disabled (the app used 9GB of mobile data this month lol) Are you aware of these issues? Do you need any additional information?
Author
Owner

@xdaniel9 commented on GitHub (Jul 8, 2024):

It would be great to add the feature to select upload destination for mobile app for users have more than one device, eg iphone, ipad, android phones

@xdaniel9 commented on GitHub (Jul 8, 2024): It would be great to add the feature to select upload destination for mobile app for users have more than one device, eg iphone, ipad, android phones
Author
Owner

@TriplEight commented on GitHub (Dec 10, 2024):

  1. Files getting stuck in the upload queue.

While Remainder == 0, I have several videos stuck in the upload queue. Some videos 100-900 Mb just keep being uploaded over and over.
No logs on the server side.

Negative remainder count

I have not negative, but Total amount < Backup in Android app.

image

@TriplEight commented on GitHub (Dec 10, 2024): > 1. Files getting stuck in the upload queue. While Remainder == 0, I have several videos stuck in the upload queue. Some videos 100-900 Mb just keep being uploaded over and over. No logs on the server side. > Negative remainder count I have not negative, but Total amount < Backup in Android app. <details> ![image](https://github.com/user-attachments/assets/7f0b05a0-55ec-4680-a807-c10f0d7af92a) </details>
Author
Owner

@TriplEight commented on GitHub (Dec 16, 2024):

Uploading the files that are stuck leads to an error:

image

Renaming these files won't help.

Verbose log of the server app has nothing useful about this.

@TriplEight commented on GitHub (Dec 16, 2024): Uploading the files that are stuck leads to an error: <details> ![image](https://github.com/user-attachments/assets/82599b1c-8683-4418-8925-552ad1092ec6) </details> Renaming these files won't help. Verbose log of the server app has nothing useful about this.
Author
Owner

@bo0tzz commented on GitHub (Dec 16, 2024):

You're using something with a body size limit in front of Immich. Usually either a reverse proxy or Cloudflare. See https://immich.app/docs/administration/reverse-proxy

@bo0tzz commented on GitHub (Dec 16, 2024): You're using something with a body size limit in front of Immich. Usually either a reverse proxy or Cloudflare. See https://immich.app/docs/administration/reverse-proxy
Author
Owner

@TriplEight commented on GitHub (Dec 17, 2024):

@bo0tzz yes I use cloudflared w default config. And you were right, it was the cause.

I'll leave a workaround for this here:

  1. go to app -> Settings -> Networking
  2. set your home WiFi netwirk, give "always" location permission and set your local address of your immich instance.
@TriplEight commented on GitHub (Dec 17, 2024): @bo0tzz yes I use cloudflared w default config. And you were right, it was the cause. I'll leave a workaround for this here: 1. go to app -> Settings -> Networking 2. set your home WiFi netwirk, give "always" location permission and set your local address of your immich instance.
Author
Owner

@suzucappo commented on GitHub (Feb 28, 2025):

Similar/Same issue here on two different phones.

Edit: I first found issue 5994 which seemed to be pushed over to here, but was closed (I think due to it being related to CloudFlare issues) However as I noted below I am strictly using local network access for testing and have turned off the domain link in the app for those purposes. If this needs to go somewhere else please let me know.

Server Version
1.127.0

Mobile App Version
1.127.0 b.185

Galaxy S23 Ultra
Unrestricted battery usage
Location access all the time
Background mobile data usage enabled
DCIM/Camera directory selected as backup location

Pixel 9 Pro (GrapheneOS)
Unrestricted battery usage
Location access all the time
Background mobile data usage enabled
DCIM/Camera directory selected as backup location (through storage scope)

Both devices function exactly the same in terms of the issue.

I do have a proxy through CloudFlare to my domain but for testing purposes am using local network access.

Failover to domain works when not on local network, and proceeding to use local network when it is recognized is working when the app is opened.

Unrestricted battery usage is for sure working on the Pixel as I have some other apps that run in the background for work and school notifications etc.

Here are a couple of logs from my Pixel

App running in background (still in the open apps drawer) >> took 3 pictures and there is a change in the log that seems to imply that the app is trying or waiting to backup files.

`02-28 19:33:28.923 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:33:39.212 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:34:00.218 27257 1392 D BackupWorker: enqueueBackupWorker: BackupWorker enqueued

02-28 19:34:16.358 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:34:32.240 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:34:39.219 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:34:44.897 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:34:47.995 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:35:03.881 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:35:07.045 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:35:22.843 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:35:32.403 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:35:32.946 27257 27905 D BackupWorker: enqueueBackupWorker: BackupWorker enqueued

02-28 19:35:39.227 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:35:54.583 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.`

The above JobService output continues until this time stamp.

02-28 19:36:54.731 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

Brought app to foreground >> Backup service starts > Files backed up > Flip over to the home screen so immich is in the background and the JobService output starts again.

`--------- switch to events
02-28 19:37:08.509 27257 27257 I wm_on_restart_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=performRestart,time=0ms]

02-28 19:37:08.511 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately]

02-28 19:37:08.511 27257 27257 I wm_on_start_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=handleStartActivity,time=1ms]

02-28 19:37:08.519 27257 27257 I wm_on_resume_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=RESUME_ACTIVITY,time=1ms]

02-28 19:37:08.519 27257 27257 I wm_on_top_resumed_gained_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=topWhenResuming]

02-28 19:37:08.520 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately]

--------- switch to main

02-28 19:37:08.523 27257 27291 I flutter : [APP STATE] hidden

02-28 19:37:08.524 27257 27291 I flutter : [APP STATE] inactive

--------- switch to events

02-28 19:37:08.533 27257 27257 I surfaceview_layout: [window=SV[162700059 MainActivity],format=4,width=960,height=2142,z=-2,sizeFrom=layout,attached=1,lifecycleStrategy=0,viewVisible=1]

02-28 19:37:08.535 27257 27257 I surfaceview_callback: [window=SV[162700059 MainActivity],callback=surfaceCreated]

02-28 19:37:08.537 27257 27257 I surfaceview_callback: [window=SV[162700059 MainActivity],callback=surfaceChanged -- format=4 w=960 h=2142]

02-28 19:37:08.537 27257 27257 I surfaceview_callback: [window=SV[162700059 MainActivity],callback=surfaceRedrawNeeded]

02-28 19:37:08.538 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=Start draw after previous draw not visible]

02-28 19:37:08.555 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=reportDrawFinished seqId=0]

--------- switch to main

02-28 19:37:08.580 27257 27291 I flutter : [APP STATE] resumed

02-28 19:37:08.631 27257 27291 I flutter : [INFO] [2025-02-28 11:37:08.631070] [_resumeBackup] Start back up

02-28 19:37:08.631 27257 27291 I flutter : Start backup process

02-28 19:37:08.659 27257 27291 I flutter : [INFO] [2025-02-28 11:37:08.659477] Found 2 local albums

02-28 19:37:08.708 27257 27291 I flutter : [INFO] [2025-02-28 11:37:08.707949] _getBackupAlbumsInfo: Found 2 available albums

02-28 19:37:08.708 27257 27291 I flutter : _getBackupAlbumsInfo takes 76ms

02-28 19:37:10.365 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:37:11.605 27257 27257 D ContentObserverWorker: enabled ContentObserverWorker

02-28 19:37:11.792 27257 27291 I flutter : [INFO] [2025-02-28 11:37:11.792610] Upserted 6 assets into the DB

02-28 19:37:11.794 27257 27291 I flutter : refreshRemoteAssets full took 89ms

02-28 19:37:11.854 27257 27291 I flutter : [INFO] [2025-02-28 11:37:11.853990] Found 2 device albums

02-28 19:37:11.854 27257 27291 I flutter : [INFO] [2025-02-28 11:37:11.854353] 'Recents' is not selected, keeping only selected albums

02-28 19:37:12.114 27257 27291 I flutter : [INFO] [2025-02-28 11:37:12.114400] Synced changes of local album Camera to DB

02-28 19:37:12.172 27257 27291 I flutter : [INFO] [2025-02-28 11:37:12.172317] Removed 0 and updated 3 local assets from DB

02-28 19:37:12.172 27257 27291 I flutter : [INFO] [2025-02-28 11:37:12.172566] Syncing completed. Changes: true

02-28 19:37:12.172 27257 27291 I flutter : refreshDeviceAlbums took 378ms

02-28 19:37:12.172 27257 27291 I flutter : changedUsers: true, newRemote: true, newLocal: true

02-28 19:37:12.172 27257 27291 I flutter : [INFO] [2025-02-28 11:37:12.172668] Load assets: 556ms

02-28 19:37:12.172 27257 27291 I flutter : Attempting to connect to websocket

02-28 19:37:12.200 27257 27257 D ContentObserverWorker: enabled ContentObserverWorker

02-28 19:37:12.200 27257 27291 I flutter : Established Websocket Connection

02-28 19:37:12.717 27257 27270 W app.alextran.immich: Reducing the number of considered missed Gc histogram
windows from 315 to 100

--------- switch to events

02-28 19:37:14.780 27257 27257 I wm_on_top_resumed_lost_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=topStateChangedWhenResumed]

02-28 19:37:14.782 27257 27257 I wm_on_paused_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=performPause,time=0ms]

--------- switch to main

02-28 19:37:14.782 27257 27291 I flutter : [APP STATE] inactive

02-28 19:37:15.032 27257 27257 D VRI[MainActivity]: visibilityChanged oldVisibility=true newVisibility=false

--------- switch to events

02-28 19:37:15.035 27257 27257 I surfaceview_layout: [window=SV[162700059 MainActivity],format=4,width=960,height=2142,z=-2,sizeFrom=layout,attached=1,lifecycleStrategy=0,viewVisible=0]

02-28 19:37:15.036 27257 27257 I surfaceview_callback: [window=SV[162700059 MainActivity],callback=surfaceDestroyed]

02-28 19:37:15.054 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately]

02-28 19:37:15.054 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately]

02-28 19:37:15.055 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=Not drawing due to not visible. Reason=!mAppVisible && !mForceDecorViewVisibility]

02-28 19:37:15.060 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately]

02-28 19:37:15.061 27257 27257 I wm_on_stop_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=STOP_ACTIVITY_ITEM,time=2ms]

02-28 19:37:15.067 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately]

--------- switch to main

02-28 19:37:15.158 27257 27291 I flutter : [APP STATE] hidden

02-28 19:37:15.158 27257 27291 I flutter : [APP STATE] paused

02-28 19:37:15.158 27257 27291 I flutter : Attempting to disconnect from websocket

02-28 19:37:15.159 27257 27291 I flutter : Disconnect to Websocket Connection

02-28 19:37:16.597 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.

02-28 19:37:19.756 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.`

Please let me know if these are helpful in any way or if there are other logs I could grab that may assist in getting the background upload working.

@suzucappo commented on GitHub (Feb 28, 2025): Similar/Same issue here on two different phones. Edit: I first found issue 5994 which seemed to be pushed over to here, but was closed (I think due to it being related to CloudFlare issues) However as I noted below I am strictly using local network access for testing and have turned off the domain link in the app for those purposes. If this needs to go somewhere else please let me know. Server Version 1.127.0 Mobile App Version 1.127.0 b.185 Galaxy S23 Ultra Unrestricted battery usage Location access all the time Background mobile data usage enabled DCIM/Camera directory selected as backup location Pixel 9 Pro (GrapheneOS) Unrestricted battery usage Location access all the time Background mobile data usage enabled DCIM/Camera directory selected as backup location (through storage scope) Both devices function exactly the same in terms of the issue. I do have a proxy through CloudFlare to my domain but for testing purposes am using local network access. Failover to domain works when not on local network, and proceeding to use local network when it is recognized is working when the app is opened. Unrestricted battery usage is for sure working on the Pixel as I have some other apps that run in the background for work and school notifications etc. Here are a couple of logs from my Pixel App running in background (still in the open apps drawer) >> took 3 pictures and there is a change in the log that seems to imply that the app is trying or waiting to backup files. `02-28 19:33:28.923 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:33:39.212 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:34:00.218 27257 1392 D BackupWorker: enqueueBackupWorker: BackupWorker enqueued 02-28 19:34:16.358 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:34:32.240 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:34:39.219 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:34:44.897 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:34:47.995 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:35:03.881 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:35:07.045 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:35:22.843 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:35:32.403 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:35:32.946 27257 27905 D BackupWorker: enqueueBackupWorker: BackupWorker enqueued 02-28 19:35:39.227 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:35:54.583 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.` The above JobService output continues until this time stamp. `02-28 19:36:54.731 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.` Brought app to foreground >> Backup service starts > Files backed up > Flip over to the home screen so immich is in the background and the JobService output starts again. `--------- switch to events 02-28 19:37:08.509 27257 27257 I wm_on_restart_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=performRestart,time=0ms] 02-28 19:37:08.511 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately] 02-28 19:37:08.511 27257 27257 I wm_on_start_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=handleStartActivity,time=1ms] 02-28 19:37:08.519 27257 27257 I wm_on_resume_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=RESUME_ACTIVITY,time=1ms] 02-28 19:37:08.519 27257 27257 I wm_on_top_resumed_gained_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=topWhenResuming] 02-28 19:37:08.520 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately] --------- switch to main 02-28 19:37:08.523 27257 27291 I flutter : [APP STATE] hidden 02-28 19:37:08.524 27257 27291 I flutter : [APP STATE] inactive --------- switch to events 02-28 19:37:08.533 27257 27257 I surfaceview_layout: [window=SV[162700059 MainActivity],format=4,width=960,height=2142,z=-2,sizeFrom=layout,attached=1,lifecycleStrategy=0,viewVisible=1] 02-28 19:37:08.535 27257 27257 I surfaceview_callback: [window=SV[162700059 MainActivity],callback=surfaceCreated] 02-28 19:37:08.537 27257 27257 I surfaceview_callback: [window=SV[162700059 MainActivity],callback=surfaceChanged -- format=4 w=960 h=2142] 02-28 19:37:08.537 27257 27257 I surfaceview_callback: [window=SV[162700059 MainActivity],callback=surfaceRedrawNeeded] 02-28 19:37:08.538 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=Start draw after previous draw not visible] 02-28 19:37:08.555 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=reportDrawFinished seqId=0] --------- switch to main 02-28 19:37:08.580 27257 27291 I flutter : [APP STATE] resumed 02-28 19:37:08.631 27257 27291 I flutter : [INFO] [2025-02-28 11:37:08.631070] [_resumeBackup] Start back up 02-28 19:37:08.631 27257 27291 I flutter : Start backup process 02-28 19:37:08.659 27257 27291 I flutter : [INFO] [2025-02-28 11:37:08.659477] Found 2 local albums 02-28 19:37:08.708 27257 27291 I flutter : [INFO] [2025-02-28 11:37:08.707949] _getBackupAlbumsInfo: Found 2 available albums 02-28 19:37:08.708 27257 27291 I flutter : _getBackupAlbumsInfo takes 76ms 02-28 19:37:10.365 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:37:11.605 27257 27257 D ContentObserverWorker: enabled ContentObserverWorker 02-28 19:37:11.792 27257 27291 I flutter : [INFO] [2025-02-28 11:37:11.792610] Upserted 6 assets into the DB 02-28 19:37:11.794 27257 27291 I flutter : refreshRemoteAssets full took 89ms 02-28 19:37:11.854 27257 27291 I flutter : [INFO] [2025-02-28 11:37:11.853990] Found 2 device albums 02-28 19:37:11.854 27257 27291 I flutter : [INFO] [2025-02-28 11:37:11.854353] 'Recents' is not selected, keeping only selected albums 02-28 19:37:12.114 27257 27291 I flutter : [INFO] [2025-02-28 11:37:12.114400] Synced changes of local album Camera to DB 02-28 19:37:12.172 27257 27291 I flutter : [INFO] [2025-02-28 11:37:12.172317] Removed 0 and updated 3 local assets from DB 02-28 19:37:12.172 27257 27291 I flutter : [INFO] [2025-02-28 11:37:12.172566] Syncing completed. Changes: true 02-28 19:37:12.172 27257 27291 I flutter : refreshDeviceAlbums took 378ms 02-28 19:37:12.172 27257 27291 I flutter : changedUsers: true, newRemote: true, newLocal: true 02-28 19:37:12.172 27257 27291 I flutter : [INFO] [2025-02-28 11:37:12.172668] Load assets: 556ms 02-28 19:37:12.172 27257 27291 I flutter : Attempting to connect to websocket 02-28 19:37:12.200 27257 27257 D ContentObserverWorker: enabled ContentObserverWorker 02-28 19:37:12.200 27257 27291 I flutter : Established Websocket Connection 02-28 19:37:12.717 27257 27270 W app.alextran.immich: Reducing the number of considered missed Gc histogram windows from 315 to 100 --------- switch to events 02-28 19:37:14.780 27257 27257 I wm_on_top_resumed_lost_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=topStateChangedWhenResumed] 02-28 19:37:14.782 27257 27257 I wm_on_paused_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=performPause,time=0ms] --------- switch to main 02-28 19:37:14.782 27257 27291 I flutter : [APP STATE] inactive 02-28 19:37:15.032 27257 27257 D VRI[MainActivity]: visibilityChanged oldVisibility=true newVisibility=false --------- switch to events 02-28 19:37:15.035 27257 27257 I surfaceview_layout: [window=SV[162700059 MainActivity],format=4,width=960,height=2142,z=-2,sizeFrom=layout,attached=1,lifecycleStrategy=0,viewVisible=0] 02-28 19:37:15.036 27257 27257 I surfaceview_callback: [window=SV[162700059 MainActivity],callback=surfaceDestroyed] 02-28 19:37:15.054 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately] 02-28 19:37:15.054 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately] 02-28 19:37:15.055 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=Not drawing due to not visible. Reason=!mAppVisible && !mForceDecorViewVisibility] 02-28 19:37:15.060 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately] 02-28 19:37:15.061 27257 27257 I wm_on_stop_called: [Token=#########,Component Name=app.alextran.immich.MainActivity,Reason=STOP_ACTIVITY_ITEM,time=2ms] 02-28 19:37:15.067 27257 27257 I viewroot_draw_event: [window=VRI[MainActivity],event=applyTransactionOnDraw applyImmediately] --------- switch to main 02-28 19:37:15.158 27257 27291 I flutter : [APP STATE] hidden 02-28 19:37:15.158 27257 27291 I flutter : [APP STATE] paused 02-28 19:37:15.158 27257 27291 I flutter : Attempting to disconnect from websocket 02-28 19:37:15.159 27257 27291 I flutter : Disconnect to Websocket Connection 02-28 19:37:16.597 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass. 02-28 19:37:19.756 27257 27257 W JobService: onNetworkChanged() not implemented in androidx.work.impl.background.systemjob.SystemJobService. Must override in a subclass.` Please let me know if these are helpful in any way or if there are other logs I could grab that may assist in getting the background upload working.
Author
Owner

@alextran1502 commented on GitHub (Feb 28, 2025):

@garcia1987 the bug you described is fixed and waiting on app store approval on v1.128.0

@alextran1502 commented on GitHub (Feb 28, 2025): @garcia1987 the bug you described is fixed and waiting on app store approval on v1.128.0
Author
Owner

@suzucappo commented on GitHub (Feb 28, 2025):

Awesome, thank you for letting me know.

Great work you all are doing here!

@suzucappo commented on GitHub (Feb 28, 2025): Awesome, thank you for letting me know. Great work you all are doing here!
Author
Owner

@polaroidkidd commented on GitHub (May 31, 2025):

In the department of error reporting, are there plans to include any user feedback when an upload fails? I am asling because I recently started using immich and discovered that the uploads were all blocked by a cloudflare OWASP configuration.The gist is that the CF WAF assigns a number for certain characteristics of a request and a score to each of those. It adds them all up for each request and declinens it if it goes beyond a set threshold. The threshold is set by the user.

This all happens before the immich server is reached. CF does return an error code though.

Anyway, the app doesn't handle this currently. I propose to include the following for dealing with said scenario

  1. Configurable notification setting to ping the user if an upload has failed
  2. Mark the image with an error icon of sorts in the library
  3. Filter the user library by failed upload and allow a retry mechanism. This would have to take into account if images from multiple albums failed. They should be added to their respective albums.

I can provide the CF logs if you're interested. The post to /API/assets did trigger a larger number of warnings. Maybe that's something that should be evaluated as these WAF rules are OSWAP spec (I think?) and are in the same category as the "managed by cloudflare" rule set. Perhaps there's some credence to them, but I feel like that's a separate task.

Let me know. I'm willing to help out with this.

@polaroidkidd commented on GitHub (May 31, 2025): In the department of error reporting, are there plans to include any user feedback when an upload fails? I am asling because I recently started using immich and discovered that the uploads were all blocked by a cloudflare OWASP configuration.The gist is that the CF WAF assigns a number for certain characteristics of a request and a score to each of those. It adds them all up for each request and declinens it if it goes beyond a set threshold. The threshold is set by the user. This all happens before the immich server is reached. CF does return an error code though. Anyway, the app doesn't handle this currently. I propose to include the following for dealing with said scenario 1. Configurable notification setting to ping the user if an upload has failed 2. Mark the image with an error icon of sorts in the library 3. Filter the user library by failed upload and allow a retry mechanism. This would have to take into account if images from multiple albums failed. They should be added to their respective albums. I can provide the CF logs if you're interested. The post to /API/assets did trigger a larger number of warnings. Maybe that's something that should be evaluated as these WAF rules are OSWAP spec (I think?) and are in the same category as the "managed by cloudflare" rule set. Perhaps there's some credence to them, but I feel like that's a separate task. Let me know. I'm willing to help out with this.
Author
Owner

@tayl commented on GitHub (Jun 2, 2025):

This may be a relevant request for this.. have you thought about refactoring the upload process itself to allow for resuming failed uploads rather than restarting entirely? My mobile network coverage is pretty spotty, and I find that I'll have videos failing upload for days before finally making it up, either by sheer luck or because I happened to be back home and on wifi. Images and shorter videos are fine, it's just larger videos that take more time have a higher chance of the connection dropping.

A side effect of this issue is that my phone will burn through battery and data trying to upload these larger files. Luckily I have unlimited data, but if I didn't, I can see this being a major downside. From the battery and inconvenience standpoint alone it's a pretty big downside.

@tayl commented on GitHub (Jun 2, 2025): This may be a relevant request for this.. have you thought about refactoring the upload process itself to allow for resuming failed uploads rather than restarting entirely? My mobile network coverage is pretty spotty, and I find that I'll have videos failing upload for days before finally making it up, either by sheer luck or because I happened to be back home and on wifi. Images and shorter videos are fine, it's just larger videos that take more time have a higher chance of the connection dropping. A side effect of this issue is that my phone will burn through battery and data trying to upload these larger files. Luckily I have unlimited data, but if I didn't, I can see this being a major downside. From the battery and inconvenience standpoint alone it's a pretty big downside.
Author
Owner

@bo0tzz commented on GitHub (Jun 2, 2025):

allow for resuming failed uploads rather than restarting entirely?

That would be #1674.

@bo0tzz commented on GitHub (Jun 2, 2025): > allow for resuming failed uploads rather than restarting entirely? That would be #1674.
Author
Owner

@tayl commented on GitHub (Jun 2, 2025):

allow for resuming failed uploads rather than restarting entirely?

That would be #1674.

Ah okay, thanks. I see that was closed and marked only as a "nice to have". For me (and others it seems), this is a pretty critical issue that Immich suffers from. Other solutions in the space don't have this same issue (i.e. Google Photos), so maybe it's still something to look at even as a stretch goal for this issue - IMO it's tech debt.

@tayl commented on GitHub (Jun 2, 2025): > > allow for resuming failed uploads rather than restarting entirely? > > That would be [#1674](https://github.com/immich-app/immich/discussions/1674). Ah okay, thanks. I see that was closed and marked only as a "nice to have". For me (and others it seems), this is a pretty critical issue that Immich suffers from. Other solutions in the space don't have this same issue (i.e. Google Photos), so maybe it's still something to look at even as a stretch goal for this issue - IMO it's tech debt.
Author
Owner

@bo0tzz commented on GitHub (Jun 2, 2025):

To clarify, it wasn't closed, just locked.

@bo0tzz commented on GitHub (Jun 2, 2025): To clarify, it wasn't closed, just locked.
Author
Owner

@ngdangtu-vn commented on GitHub (Jul 23, 2025):

I think in my case quota limit is partially a reason of broken. And it still happens after increasing the quota.

Log from server:

[Nest] 16  - 07/22/2025, 6:21:32 AM   ERROR [Api:AssetMediaService~aeudlyfl] Error uploading file BadRequestException: Quota has been exceeded!
BadRequestException: Quota has been exceeded!
    at AssetMediaService.requireQuota (/usr/src/app/dist/services/asset-media.service.js:299:19)
    at AssetMediaService.uploadAsset (/usr/src/app/dist/services/asset-media.service.js:96:18)
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
    at async AssetMediaController.uploadAsset (/usr/src/app/dist/controllers/asset-media.controller.js:40:29)
@ngdangtu-vn commented on GitHub (Jul 23, 2025): I think in my case quota limit is partially a reason of broken. And it still happens after increasing the quota. Log from server: ``` [Nest] 16 - 07/22/2025, 6:21:32 AM ERROR [Api:AssetMediaService~aeudlyfl] Error uploading file BadRequestException: Quota has been exceeded! BadRequestException: Quota has been exceeded! at AssetMediaService.requireQuota (/usr/src/app/dist/services/asset-media.service.js:299:19) at AssetMediaService.uploadAsset (/usr/src/app/dist/services/asset-media.service.js:96:18) at process.processTicksAndRejections (node:internal/process/task_queues:105:5) at async AssetMediaController.uploadAsset (/usr/src/app/dist/controllers/asset-media.controller.js:40:29) ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: immich-app/immich#886