Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

shllghst's avatar

Send Notification from Laravel Nova Action

Hello,

I can't manage to send a Notification from a Nova Action that is queued.

Here is the Action :

class UpdateBackupJob extends Action implements ShouldQueue
{
    use InteractsWithQueue, Queueable;

    ...

    /**
     * Perform the action on the given models.
     *
     * @param  \Laravel\Nova\Fields\ActionFields  $fields
     * @param  \Illuminate\Support\Collection  $models
     * @return mixed
     */
    public function handle(ActionFields $fields, Collection $models)
    {
        foreach ($models as $model) {
            $res = Artisan::call('backup-jobs:update ' . $model->host->fqdn);

            if ($res >= 1) {
                $this->markAsFinished($model);

                auth()->user()->notify(new BackupJobUpdateFinished($model));
            } else {
                $this->markAsFailed($model);

                auth()->user()->notify(new BackupJobUpdateFailed($model));
            }
        }
    }

    ...
}

It is working when I remove ShouldQueue. The Notification is sent via database and broadcast. But with ShouldQueue the database record isn't even created.

Can someone help please ?

0 likes
1 reply
stevenfox's avatar

My first hunch is that auth()->user() is null once the queued job is handled asynchronously.

Perhaps you could run this locally with dd(auth()->user()) to verify my hunch. However, I'd also imagine you'd be getting a cannot call method 'notify' on null style exception if you run this currently and my hunch is accurate. Does this land in your failed jobs list with an exception if you run it?

Tip: if you do test locally, remember to set your local environment's QUEUE_CONNECTION to something other than sync or null. Otherwise, you'll get unhelpful results, as the action will be handled synchronously (during the request) when auth()->user() is non-null (or in the case of a null queue connection, the job won't be handled at all).

Assuming I'm correct, here are some recommendations to solve the issue:

Since it's evident from your code that you're attempting to notify the admin using Nova that triggered the action, perhaps you could resolve the user from a database query instead of the auth()->user() helper. Something like:

User::getDefaultAdmin()->notify(new BackupJobUpdateFinished($model));

If you have multiple admins of your system, then you might be looking to resolve the specific admin that started the action. In that case, I'd recommend:

  1. In the action's handle method, manually dispatch a BackupJob for the $models, where you can pass in a particular $user to the job's constructor to use for your notification. This also let's this "job handling" logic exist in one place and your Nova action simply leverages that existing code, staying DRY. Not to mention, this lets you utilize the failed() method of Laravel's Job class to handle the notification so that you can get away from the if ... else logic. https://laravel.com/docs/8.x/queues#cleaning-up-after-failed-jobs. Obviously, if you choose this path, your Nova action itself no longer needs to be queued.
  2. Alternatively, you might be able to use the Nova action's __construct() method to pass in the particular admin user and that should get serialized into the job. I honestly haven't tried this strategy before, because I prefer to leverage my existing Jobs in the system (the option above). Nonetheless, if this does work, then you could do something like:
// Nova action

public User $admin;

public function __construct(?User $admin = null)
{
	$this->admin = $admin ?? auth()->user();
}

public function handle(ActionFields $fields, Collection $models)
{
	foreach ($models as $model) {
        $res = Artisan::call('backup-jobs:update ' . $model->host->fqdn);

        if ($res >= 1) {
        	$this->markAsFinished($model);

            $this->admin->notify(new BackupJobUpdateFinished($model));
        } else {
            $this->markAsFailed($model);

            $this->admin->notify(new BackupJobUpdateFailed($model));
        }
    }
}

Hope this helps.

Please or to participate in this conversation.