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

ignaciodev's avatar

Email Notifications Only Get Sent When Not Queued

I have a pretty simple notification:

class MerchantOrderNotificationEmail extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        // ...
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->subject('New order')
                    ->greeting("Dear {$notifiable->shop_name},")
                    ->line("Some of your items just got purchased.")
                    ->line('Please, press the button below to find out more.')
                    ->action("View orders", url('/'));
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

When I do $merchant->notify(new MerchantOrderNotificationEmail()), the email gets sent no problem, and I get it from MailTrap.

However, the moment I add implements ShouldQueue to my MerchantOrderNotificationEmail, the queue says this:

2023-05-15 11:38:11 App\Notifications\MerchantOrderNotificationEmail  81.19ms DONE

But the email never arrives... why could this be?

I am using the database driver, and all the migrations have been executed.

0 likes
41 replies
Snapey's avatar

and the job is added and removed from the queue?

Snapey's avatar

@ignaciodev have you made any changes to email config, and if so, have you restarted the queue worker?

ignaciodev's avatar

@Snapey all i ever did was adding my mailtrap credentials to the .env file. They work fine, the email are arriving when not queueing.

And yes, I have tried restarting the queue worker.

I am on the development environment using queue:listen. I have been trying queue:work as well, but same results.

Email Notifications get sent when they are not queued. When they are queued, they are marked as done and removed. Email is not sent.

I'm on Laravel 9.

newbie360's avatar

@ignaciodev just make sure you changed this in .env ?

QUEUE_CONNECTION=database

and both failed_jobs and jobs table is empty ?

try to clear the cache(make sure /storage/framework/cache/data has .gitignore ONLY) and restart queue work

ignaciodev's avatar

@newbie360 Yes, I have setup the .env QUEUE_CONNECTION to database, and ran the queue migrations.

'failed_jobs' and 'jobs' are both empty. My 'queue:listen' shows this:

2023-05-15 13:00:09 App\Notifications\MerchantOrderNotificationEmail  82.83ms DONE

But the email does not arrive to MailTrap.

However, when I don't implement ShouleQueue, the email arrives fine.

newbie360's avatar

@ignaciodev when you playing around how the queue to work, do you have any un-released lock cached, and you manually refresh all migration, try to clear the cache

Snapey's avatar

Anything in the logs file?

Try logging in the job

    public function toMail($notifiable)
    {
		Log::info($notifiable);

        return (new MailMessage)
                    ->subject('New order')
                    ->greeting("Dear {$notifiable->shop_name},")
                    ->line("Some of your items just got purchased.")
                    ->line('Please, press the button below to find out more.')
                    ->action("View orders", url('/'));
    }
ignaciodev's avatar

@Snapey Very interesting.. I tried this:

public function toMail($notifiable)
    {
		Log::info('DEBUG NOTIFIABLE');
		Log::info($notifiable);

        return (new MailMessage)
                    ->subject('New order')
                    ->greeting("Dear {$notifiable->shop_name},")
                    ->line("Some of your items just got purchased.")
                    ->line('Please, press the button below to find out more.')
                    ->action("View orders", url('/'));
    }

None of those log lines appear in the log. It's like toMail() is never being called...

ignaciodev's avatar

Yet, the moment I remove implements ShouldQueue, it logs both lines fine :/

Snapey's avatar

I think you need to add the interface

class MerchantOrderNotificationEmail extends Notification implements ShouldQueue

You have the Queueable trait installed, but make sure its the right use Illuminate\Bus\Queueable;

ignaciodev's avatar

@Snapey The interface is added. When I remove it, the email is received. When I add it, the email is not recieved.

ignaciodev's avatar

@dacfabre When I use sendNow() instead, the notification is not added to the queue, and I receive the email perfectly.

ignaciodev's avatar

@dacfabre No, on the code description, I show that when ShouldQueue is NOT present, the email gets sent fine. But the moment I implement ShouldQueue, everything shows up fine in the queue, but the email is not received.

newbie360's avatar

@ignaciodev your problem seem is not even queued to the jobs table, you can try

$merchant->notify(new MerchantOrderNotificationEmail())
    ->delay(now()->addMinutes(3)));

and check the jobs table, there should be empty

ignaciodev's avatar

@dacfabre sure:

[2023-05-15 14:00:23] local.INFO: {"id":1,"first_name":"John","last_name":"Doe","country_code":"ES","shop_name":"El Corte Ingles","shop_slug":"el-corte-ingles","email":"[email protected]","email_verified_at":"2023-05-04T11:04:36.000000Z","can_sell":true,"created_at":"2023-05-04T11:01:11.000000Z","updated_at":"2023-05-04T11:07:21.000000Z","full_name":"Ignacio Dominguez Camejo","currency":{"code":"EUR","title":"Euro","symbol":"\u20ac","precision":2,"thousandSeparator":".","decimalSeparator":",","symbolPlacement":"after"}}  
Snapey's avatar

did you check the class paths as suggested?

From the docs

<?php
 
namespace App\Notifications;
 
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
 
class InvoicePaid extends Notification implements ShouldQueue
{
    use Queueable;
 
    // ...
}

make sure you have the same use statements.

These are for Laravel 10. What version are you running?

ignaciodev's avatar

@Snapey Yes. This is my whole class with the queue implemented:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;

class MerchantOrderNotificationEmail extends Notification implements ShouldQueue
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        //

    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->subject('New order')
                    ->greeting("Dear {$notifiable->shop_name},")
                    ->line("Some of your items just got purchased.")
                    ->line('Please, press the button below to find out more.')
                    ->action("View orders", url('/'));
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}
ignaciodev's avatar

When I log the $notifiable from via(), it gets logged. When I log it from toMail(), it does not log it (when implementing ShouldQueue).

For some reason, the queue is not calling the toMail() method.

dacfabre's avatar

@ignaciodev can you try minimize your payload by just selecting the id and shop name, also remove the currency relationship

ignaciodev's avatar

@dacfabre what for exactly? the payload is working fine, and the email gets sent when not in the queue.

ignaciodev's avatar

The only workaround I have found is to create a queueable Job, andsend the email notification from the Job.

newbie360's avatar

@ignaciodev what happen when you

    public function toMail($notifiable)
    {
		info('1st', [$notifiable->shop_name]);
		info('2nd', [$this->shop_name]);

        return (new MailMessage)
                    ->subject('New order')
                    ->greeting("Dear {$notifiable->shop_name},")
                    ->line("Some of your items just got purchased.")
                    ->line('Please, press the button below to find out more.')
                    ->action("View orders", url('/'));
    }
ignaciodev's avatar

@newbie360 I understand, thank you so much for your time!! I give up too.. I am going to use a Job instead, which seems to be working fine 🥴

Snapey's avatar

does your Merchant model use the notifiable trait?

ignaciodev's avatar

@Snapey yes! If it didn't, the email would not send without the queue. The issue is: when I implement the ShoulQueue contract, the toMail() method is never called.

Snapey's avatar

@ignaciodev not taking anything for granted at this point - and you don't need to keep reiterating the issue.

There is something different about the merchant that is used immediately, and the merchant that is re-hydrated within the queued job.

1 like
ignaciodev's avatar
ignaciodev
OP
Best Answer
Level 2

Ok I found the issue.

I was using a third party library to use hashids instead of ids on the routes.

This library was replacing the getKey() method of my models, instead of the getRouteKey().

After switching to a different library, everything is working normally.

Thank you everyone for your help!

Snapey's avatar

@ignaciodev ahem

There is something different about the merchant that is used immediately, and the merchant that is re-hydrated within the queued job.

1 like

Please or to participate in this conversation.