Guilherme Freire
Guilherme Freire

Reputation: 372

Notification don't work on queue but work as Direct

i have a issue with notifications on laravel, if i send a notification directly without a queue this work as well

this notifiction needs send a email and save in database

i use this to call notify as exemple

$user = \App\User::find(1);
    $candidato = \App\CandidatoVaga::where('id_user','=','1')->first();
    $user->notify(new \App\Notifications\ConviteVagaCandidato($candidato));

And this is \App\Notifications\ConviteVagaCandidato

<?php

namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
class ConviteVagaCandidato extends Notification implements ShouldQueue
{
use Queueable;
protected $CandidatoVaga;
/**
 * Create a new notification instance.
 *
 * @return void
 */
public function __construct(\App\CandidatoVaga $CandidatoVaga)
{
    $this->CandidatoVaga = $CandidatoVaga;
}
/**
 * Get the notification's delivery channels.
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function via($notifiable)
{
    return ['database','mail'];
}

/**
 * Get the mail representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
    ->greeting('Olá, '.$this->CandidatoVaga->user->DadosPessoais->nome)
    ->subject('Convite')
    ->markdown('email.convite_selecao');
}
/**
 * Get the array representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return array
 */
public function toArray($notifiable)
{
return [
        'id_vaga' => $this->CandidatoVaga->id_vaga,
        'id_user' => $this->CandidatoVaga->id_user,
        'mensagem' => 'Você foi pré selecionado para a vaga',
        'tipo' => 'Nova Vaga',
    ];
}
}

This return a sql error SQLSTATE[42601]: Syntax error: 7 ERRO but without implements ShouldQueue works as well

Upvotes: 1

Views: 2581

Answers (2)

patricus
patricus

Reputation: 62348

One of the differences between the sync queue driver and a real queue driver is how the queued job handles stored Models.

Since the sync queue driver is processing the jobs directly in the same process, there is no extra work being done. If you build your Notification with a Model, it uses that exact model instance.

However, when using a real queue, Laravel has to serialize the data stored on the notification for the queue worker to handle it. Because models cannot be serialized easily, what it actually does is just store the model key on the notification, and then when the queue worker processes that job, it re-retrieves that model from the database using the stored key.

Based on the query you mentioned in the comments, it looks to me like your \App\CandidatoVaga model does not have a primary key ($primaryKey is empty). Because of this, there is no primary key field to query ("candidatos_vaga".""), and there is no primary key value stored (is null).

I see you've already come up with a solution for yourself. If, however, you still wanted to attempt to just use the model, you can try this:

  1. Override the getQueueableId() method on your model. By default, this returns the primary key field. But, since you don't have one defined, you would need to override this method to provide some unique data that can be used to find your record again.

  2. Override the newQueryForRestoration() method on your model. By default, this builds a query using the primary key field. But, since you don't have one defined, you would need to override this method to generate a query using the data generated by the getQueueableId() method.

NB: this is untested. I have never done this; this is just what I see looking through the source code.

Upvotes: 3

Guilherme Freire
Guilherme Freire

Reputation: 372

I was able to solve it in a palliative way

public $id_vaga;
public $id_user;
public $nome;
public $titulo_vaga;
/**
 * Create a new notification instance.
 *
 * @return void
 */
public function __construct($CandidatoVaga)
{

    $this->id_vaga = $CandidatoVaga->id_vaga;
    $this->id_user = $CandidatoVaga->id_user;
    $this->nome = $CandidatoVaga->user->DadosPessoais->nome;
    $this->titulo_vaga = $CandidatoVaga->vaga->titulo_vaga;
}

Upvotes: 0

Related Questions