TimedJob: Failed to create a background job

I followed this link (https://docs.nextcloud.com/server/27/developer_manual/basics/backgroundjobs.html) to create a TimedJob.
Here’s my info.xml:

<?xml version="1.0"?>
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">

    <id>qlcv</id>
    <name>Q L C V</name>
    <summary>https://apps.nextcloud.com/developer/apps/generate</summary>
    <description><![CDATA[https://apps.nextcloud.com/developer/apps/generate]]></description>
    <version>0.0.1</version>
    <licence>agpl</licence>
    <author mail="test@gmail.com" >Lucy</author>
    <namespace>QLCV</namespace>
    <category>organization</category>
    <bugs>https://apps.nextcloud.com/developer/apps/generate</bugs>
    <dependencies>
        <nextcloud min-version="27" max-version="27"/>
    </dependencies>
    <background-jobs>
        <job>OCA\QLCV\Cron\CheckWorkDeadline</job>
    </background-jobs>
    <navigations>
        <navigation>
            <name>Quản Lý Công Việc</name>
            <route>qlcv.page.index</route>
        </navigation>
    </navigations>
</info>

And here’s CheckWorkDeadline.php:

<?php
namespace OCA\QLCV\Cron;

use OCA\QLCV\Service\WorkService;
use OCP\BackgroundJob\TimedJob;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Notification\IManager as NotificationManager;
use OCA\QLCV\Notification\NotificationHelper;
use OCP\ILogger;

class CheckWorkDeadline extends TimedJob {

    private $workService;
    private $notificationHelper;

    private NotificationManager $notificationManager;
    protected $logger;

    public function __construct(ITimeFactory $time, WorkService $workService, NotificationManager $notificationManager, ILogger $logger) {
        parent::__construct($time);
        $this->workService = $workService;
        $this->notificationHelper = new NotificationHelper(
            $notificationManager
        );
        $this->logger = $logger;

        $this->setInterval(360);
    }

    protected function run($arguments) {
        $this->logger->debug('CheckWorkDeadline job is running.', ['app' => 'QLCV']);
        $works = $this->workService->getAllWorks();

        foreach ($works as $work) {
            $daysToDeadline = $this->workService->calculateDaysToDeadline($work['work_id']);

            if ($daysToDeadline === 0) {
                $this->notificationHelper->notifyDueWork($work['assigned_to'], $work['project_name'], $work['work_name']);
            } elseif ($daysToDeadline === 7) {
                $this->notificationHelper->notify7dayWork($work['assigned_to'], $work['project_name'], $work['work_name']);
            } elseif ($daysToDeadline === 30) {
                $this->notificationHelper->notify30dayWork($work['assigned_to'], $work['project_name'], $work['work_name']);
            }
        }
        $this->logger->debug('CheckWorkDeadline job has finished.', ['app' => 'QLCV']);
    }
}

I checked on table oc_jobs and couldn’t find my job. I ran sudo docker-compose exec --user www-data app php occ background-job:list but it’s the same.

I think it’s the info.xml. Yours doesn’t validate against the schema. At a minimum, you’ll need an author field after license.

https://nextcloudappstore.readthedocs.io/en/latest/developer.html#app-metadata

https://docs.nextcloud.com/server/latest/developer_manual/app_development/info.html

My apologize. My initial code includes author, but when I post on this forum, I delete it because it contains personal email.

Makes sense. What happens if you try to manually register the job instead? Background jobs (Cron) — Nextcloud latest Developer Manual latest documentation

And just to rule out the easy one: did you uninstall and re-install your app (preferably after bumping the version) after you added the job to the info.xml?

My job is for notifying if a work reaches to its deadline. So it would be better if the job starts from the time app has been installed. I also tried disable and enable the app, but nothing changes.

I tried registering the job manually by following this, but it does not work.

  1. Create TestJob.php
<?php
namespace OCA\QLCV\Cron;

use OCA\QLCV\Service\WorkService;
use OCP\BackgroundJob\TimedJob;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\ILogger;

class TestJob extends TimedJob {

    private $workService;
    private $notificationHelper;

    protected $logger;

    public function __construct(ITimeFactory $time, WorkService $workService, ILogger $logger) {
        parent::__construct($time);
        $this->workService = $workService;
        $this->logger = $logger;

        $this->setInterval(360);
    }

    protected function run($arguments) {
        $this->logger->debug('CheckWorkDeadline job is running.', ['app' => 'QLCV']);
        $this->logger->debug('CheckWorkDeadline job has finished.', ['app' => 'QLCV']);
    }
}
  1. Register it in info.xml:

<?xml version="1.0"?>
<info xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
    <!--
    SPDX-FileCopyrightText: Lucy <ct040407@actv.edu.vn>
    SPDX-License-Identifier: CC0-1.0
    -->
    <id>qlcv</id>
    <name>Q L C V</name>
    <summary>https://apps.nextcloud.com/developer/apps/generate</summary>
    <description><![CDATA[https://apps.nextcloud.com/developer/apps/generate]]></description>
    <version>0.0.1</version>
    <licence>agpl</licence>
    <author mail="test@gmail.com" >Lucy</author>
    <namespace>QLCV</namespace>
    <category>organization</category>
    <bugs>https://apps.nextcloud.com/developer/apps/generate</bugs>
    <dependencies>
        <nextcloud min-version="27" max-version="27"/>
    </dependencies>
    <background-jobs>
        <job>OCA\QLCV\Cron\CheckWorkDeadline</job>
        <job>OCA\QLCV\Cron\TestJob</job>
    </background-jobs>
    <navigations>
        <navigation>
            <name>Quản Lý Công Việc</name>
            <route>qlcv.page.index</route>
        </navigation>
    </navigations>
</info>
  1. Register it manually:
<?php
declare(strict_types=1);

namespace OCA\QLCV\Controller;

use OCP\IRequest;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse;
use OCA\QLCV\Service\ProjectService;
use OCA\QLCV\Notification\NotificationHelper;
use OCP\Notification\IManager as NotificationManager;


use OCP\BackgroundJob\IJobList;
class ProjectController extends Controller {
    private $projectService;
    private $notificationHelper;



    private IJobList $jobList;

    public function __construct(
        $AppName,
        IRequest $request,
        ProjectService $projectService,
        NotificationManager $notificationManager,


        IJobList $jobList
    ) {
        parent::__construct($AppName, $request);
        $this->projectService = $projectService;
        $this->notificationHelper = new NotificationHelper(
            $notificationManager
        );


        $this->jobList = $jobList;
    }

    /**
     * @NoAdminRequired
     * @NoCSRFRequired
     */
    public function getProjects($user_id) {
        $this->jobList->add(TestJob::class);


        $data = $this->projectService->getProjects($user_id);
        return new JSONResponse(['projects' => $data]);
    }
}

The background-jobs are only registered at app installation time or when a new version of an app is installed.

So maybe try either removing the app and fully reinstalling it or - better and more accurately - increment the version number and update it when you modify it.

So I have to uninstall my app. Then move the app folder to somewhere and move again to apps folder?

No, see the last paragraph. It should be enough to increase the version number to trigger the background job registration

But which paragraph?

This one from jtr

I changed the version in info.xml and update Nextcloud. Nothing changes. :smiling_face_with_tear: There’s no new record on oc_jobs or background-job list.

Dont know how to do. :cold_sweat:

Did you run composer dumpautoload? Maybe it can’t resolve the class.

1 Like

I have used it for Nextcloud server. After that, I check in oc_jobs but cannot find my job. I also run sudo docker-compose exec --user www-data app php occ background-job:list but there’s no my job.
I enabled Deck and can see that Deck uses background-job too. Through Github, I know the name of those jobs. I cannot find those jobs on oc_jobs or background-job:list but they’re still running!

Can you check your nextcloud.log?
Is your app otherwise functioning? It has some UI facing elements that appear, correct?

I changed the version in info.xml and update Nextcloud.

Can you elaborate on how you’re deploying your app into your test environment?

Can you see the new version listed in occ app:list or is it being ignored?

If the job isn’t showing up in the db (oc_jobs) then its definitely not registering (unless you’re using a LIMIT on the SELECT or something).

I also see you’re using v27. I don’t believe that has the enhancement where the job list limit default was increased from being really low (10) for occ. So your full job list may not be visible from the command line unless you override that:

occ background-job:list --limit=500

My app is like to-do app. When a work reaches to the deadline, a notification will be displayed. I have created database, controllers, services, UI, notificatios, files. They all work. Now for scheduling notification, I use background job. All I do is create a Cron PHP file that extends TimedJob, register it in info.xml. I don’t remember if I overridden anything related to background-job

I just set debug mode to true to modify database.

Hi. For those have the same problems, here what I found:

  1. Create your own job and register it following this: Background jobs (Cron) — Nextcloud latest Developer Manual latest documentation. Then, disable and enable your app. A new record with your job will be inserted in oc_jobs
  2. If your server runs on Linux-based system directly, set up a cron job: Background jobs — Nextcloud latest Administration Manual latest documentation.
    If your server runs on Docker, add a new cron service that mounting the server’s volume and entrypoint is /cron.sh:
cron:
  image: nextcloud:27
  restart: always
  volumes:
    - .data/server:/var/www/html
  entrypoint: /cron.sh
  networks:
    - app-network
1 Like

As I wanted to look into this but did not yet find the time: what was the difference to what you described earlier you did that did not work? My impression/interpretation was that this was your exact steps to try to get the job registered…

Christian