diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9c2be3b2ea..ffe0e289d0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,8 +6,9 @@ The format is almost based on [Keep a Changelog](https://keepachangelog.com/en/1
## [16.x.x]
### Changed
-- Added vue and ng-vue packages
-- Reimplemented relative time formatting as a filter
+- Added vue and ng-vue packages (#1421)
+- Reimplemented relative time formatting as a filter (#1450)
+- Added new `news:updater:update-user` command to update the feeds of a single user (#1360).
### Fixed
diff --git a/appinfo/info.xml b/appinfo/info.xml
index c871c782a2..3c15cce885 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -62,6 +62,7 @@ Report a [feed issue](https://github.com/nextcloud/news/discussions/new)
OCA\News\Command\ExploreGenerator
OCA\News\Command\ShowFeed
OCA\News\Command\Updater\UpdateFeed
+ OCA\News\Command\Updater\UpdateUser
OCA\News\Command\Updater\BeforeUpdate
OCA\News\Command\Updater\AfterUpdate
OCA\News\Command\Config\FolderList
diff --git a/lib/Command/Updater/UpdateUser.php b/lib/Command/Updater/UpdateUser.php
new file mode 100644
index 0000000000..0506419721
--- /dev/null
+++ b/lib/Command/Updater/UpdateUser.php
@@ -0,0 +1,70 @@
+feedService = $feedService;
+ }
+
+ /**
+ * @return void
+ */
+ protected function configure()
+ {
+ $this->setName('news:updater:update-user')
+ ->addArgument(
+ 'user-id',
+ InputArgument::REQUIRED,
+ 'user id of a user, string'
+ )
+ ->setDescription('Console API for updating a single user\'s feed');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output): int
+ {
+ $userId = $input->getArgument('user-id');
+ $feeds = $this->feedService->findAllForUser($userId);
+ $updateErrors = false;
+ foreach ($feeds as $feed) {
+ try {
+ $updated_feed = $this->feedService->fetch($feed);
+ if ($updated_feed->getUpdateErrorCount() !== 0) {
+ $output->writeln($updated_feed->getLastUpdateError());
+ $updateErrors = true;
+ }
+ } catch (Exception $e) {
+ $output->writeln(
+ 'Could not update feed with id ' . $feed->getId() .
+ '. ' . $e->getMessage() . ' '
+ );
+ return 1;
+ }
+ }
+ if ($updateErrors) {
+ return 255;
+ }
+ return 0;
+ }
+}
diff --git a/tests/Unit/Command/UpdateUserTest.php b/tests/Unit/Command/UpdateUserTest.php
new file mode 100644
index 0000000000..5d5bd8400c
--- /dev/null
+++ b/tests/Unit/Command/UpdateUserTest.php
@@ -0,0 +1,140 @@
+service = $this->getMockBuilder(FeedServiceV2::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $this->consoleInput = $this->getMockBuilder(InputInterface::class)->getMock();
+ $this->consoleOutput = $this->getMockBuilder(OutputInterface::class)->getMock();
+
+ $this->command = new UpdateUser($this->service);
+ }
+
+ /**
+ * Test a valid call will work
+ */
+ public function testValid()
+ {
+ $this->consoleInput->expects($this->exactly(1))
+ ->method('getArgument')
+ ->will($this->returnValueMap([
+ ['user-id', 'admin'],
+ ]));
+
+ $feed = $this->createMock(Feed::class);
+
+ $feed->expects($this->exactly(1))
+ ->method('getUpdateErrorCount')
+ ->willReturn(0);
+ $feed->expects($this->exactly(0))
+ ->method('getLastUpdateError');
+
+ $this->service->expects($this->exactly(1))
+ ->method('findAllForUser')
+ ->with('admin')
+ ->willReturn([$feed]);
+
+ $this->service->expects($this->exactly(1))
+ ->method('fetch')
+ ->with($feed)
+ ->willReturn($feed);
+
+ $result = $this->command->run($this->consoleInput, $this->consoleOutput);
+ $this->assertSame(0, $result);
+ }
+
+ /**
+ * Test valid calls that fails on some updates
+ */
+ public function testValidFeedError()
+ {
+ $this->consoleInput->expects($this->exactly(1))
+ ->method('getArgument')
+ ->will($this->returnValueMap([
+ ['user-id', 'admin'],
+ ]));
+
+ $feed = $this->createMock(Feed::class);
+ $feed->expects($this->exactly(1))
+ ->method('getUpdateErrorCount')
+ ->willReturn(10);
+ $feed->expects($this->exactly(1))
+ ->method('getLastUpdateError')
+ ->willReturn('Problem');
+
+ $this->service->expects($this->exactly(1))
+ ->method('findAllForUser')
+ ->with('admin')
+ ->willReturn([$feed]);
+
+ $this->service->expects($this->exactly(1))
+ ->method('fetch')
+ ->with($feed)
+ ->willReturn($feed);
+
+ $this->consoleOutput->expects($this->exactly(1))
+ ->method('writeln')
+ ->with('Problem');
+
+ $result = $this->command->run($this->consoleInput, $this->consoleOutput);
+ $this->assertSame(255, $result);
+ }
+
+ /**
+ * Test valid calls that fails completely
+ */
+ public function testInValid()
+ {
+ $this->consoleInput->expects($this->exactly(1))
+ ->method('getArgument')
+ ->will($this->returnValueMap([
+ ['user-id', 'admin'],
+ ]));
+
+ $feed = $this->createMock(Feed::class);
+
+ $this->service->expects($this->exactly(1))
+ ->method('findAllForUser')
+ ->with('admin')
+ ->willReturn([$feed]);
+
+ $this->service->expects($this->exactly(1))
+ ->method('fetch')
+ ->with($feed)
+ ->will($this->throwException(new ServiceNotFoundException('')));
+
+ $result = $this->command->run($this->consoleInput, $this->consoleOutput);
+ $this->assertSame(1, $result);
+ }
+}