Update profile image programmatically

Hi everyone,

I’m developing a Nextcloud module with ERP-like features targeted at small and medium-sized businesses. Skipping the full introduction, here are the links:

:link: GitHub - Destripador/empleados: 🚀 Employees Management Module for Nextcloud A complete employee management solution for Nextcloud, enabling businesses to efficiently handle employee records, roles, payroll, attendance, and document storage—all within their Nextcloud environment.

:link: Empleados - Apps - App Store - Nextcloud

One of the features I’m working on allows updating user profile images from within the module. It works fine, but I’ve noticed that when updating another user’s avatar (not my own), the image doesn’t refresh immediately unless I clear the browser cache or force a hard reload.

Here’s the PHP backend method I’m using:

public function uploadAvatar(): DataResponse {
	$uid = $this->request->getParam('uid');
	$file = $this->request->getUploadedFile('avatar');

	if (!$uid || !$file || !$file['tmp_name']) {
		throw new \Exception('Missing data or invalid file');
	}

	$content = file_get_contents($file['tmp_name']);
	$avatar = $this->avatarManager->getAvatar($uid);
	$avatar->set($content);

	$version = time(); // Cache-buster

	return new DataResponse(['status' => 'success', 'version' => $version]);
}

Is there an official or recommended way to force the avatar to refresh across other users or modules after it’s been updated?

Thanks in advance for any advice!

I have no solution for you but some advice: where is the problem?

What I mean: is it a browser cache problem? Is NC frontend using a cached version? Is the core sending a cached image?

You did not write how you checked the image. Just logging in as the user and going to the settings? Start to share a file where a list of possible sharees is shown with images? No big deal here, I just call it "your steps”.

To address this, you could update an image and do your steps with the web developer tools open. Then you should see if the image was requested by the browser and if the browser cache hit.

I would also check the code of the avatar manager if there is anything visible there.

Chris

1 Like

Hello @destripador ,

I had a similar problem when calculating the difference in size of files after a change. For me, it helped to clear the status cache in the method before the calculation.

clearstatcache()

Maybe it will help you too

// Example
$filesizebefore = filesize($file);
 // Here some actions for $file
file_put_contents($file, $newcontent,LOCK_EX);
clearstatcache();
$filesizeafter = filesize($file);
$filesizediff = $filesizebefore - $filesizeafter;
// without clearstatcache(); $filesizediff was always 0
1 Like

Hi!

@christianlupus

I wanted to clarify: the issue is not within my module — the profile image update works perfectly there because I handle the image URLs myself.

Animation

What I mean is that, in general, Nextcloud itself does not refresh the profile image immediately in the web interface after updating (it seems to be related to browser cache).

For example, if you use the impersonate app, log in as another user, and update their profile image, you can see that Nextcloud updates the displayed image properly across the interface.

However, if you update a user’s avatar programmatically (through code), the image eventually updates in Nextcloud after some time, but it’s not immediate and users keep seeing the old picture in the web interface for a while.

So I’m wondering: does anyone have an idea or solution for how to force the browser or Nextcloud to invalidate the cached avatar when updating a user’s image programmatically?

If you update the image by means of the frontend, there is the chance to send a notification on that browser window to all components to update/refresh a certain image.
On the other hand, if you update the image in the backend, there is no chance the frontend gets immediate feedback and reloads the image.

To confirm this, you can

  1. Keep two tabs open at the same time logged in with the same user. The second tab will probably not update. But you can test and if yes, dig into the corresponding code.
  2. You similarly test with impersonate if a user will actually see the updated images immediately.
  3. Does reloading the page help?

Still, the question is where this caching is done. It could be in the browser cache as you know or within the website as part of the vue components. There might be events in the javascript that indicated to update search images. This would need a solution provided by the nextcloud or more processly you would need to trigger this events. If it is actually the browser cash you are on a complete different page.

1 Like

I don’t think we have a way to invalidate the frontend cache for avatar requests.

1 Like

Hi all,

Thank you very much to everyone who commented and gave input on this topic.

I just want to update you:
After investigating deeper, I confirmed that while I can successfully update the avatar image from my own module, it’s not possible to force other parts of Nextcloud (like the Files app, Contacts, Deck, etc.) to immediately refresh the cached avatar image from the backend.

This is because the avatar image is cached on the browser side, and those modules use their own versioning or caching mechanisms internally. My module can control its own displayed image by adding a cache-busting version (like appending ?v=${Date.now()}), but I cannot force other modules to update or change the avatar URL they’re using without touching the Nextcloud core.

So in short:
:white_check_mark: My module’s avatar view updates immediately.
:cross_mark: Other modules’ avatar views only update after some time (when their cache expires), and I cannot control that programmatically from my app.

Again, thank you for your help! I just wanted to leave this note here for anyone else wondering about this.

If in the future Nextcloud adds a global avatar versioning API or signal, I’d be happy to implement it!

Best regards,
Luis (Crowe Mexico)

1 Like