Уведомление Laravel Broadcast – ошибка array_key_exists () при попытке отправить уведомление

Я пытаюсь отправить широковещательное уведомление пользователям при изменении данных. Но каждый раз, когда я пытаюсь отправить уведомление, я получаю эту ошибку:

array_key_exists(): The first argument should be either a string or an integer.

Вот мое уведомление:

class MyNotification extends Notification
{
    use Queueable;

    public $games;

    public $title;
    public $summary;
    public $url;

    public function __construct($games)
    {
        $this->games = $games;

        $this->title = "Your games";
        $this->summary = "Games for {$games[0]->team}";
        $this->url = "/some/url";
    }

    public function via($notifiable)
    {
        return ['mail','broadcast','database'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
            ->subject($this->title)
            ->line($this->summary);
    }

    /**
     * Get the voice representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return PushMessage
     */
    public function toPush($notifiable)
    {
        // ...
    }

    public function toBroadcast($notifiable)
    {
        return new BroadcastMessage($this->toArray($notifiable));
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            'icon' => 'fa fa-calendar',
            'text' => $this->summary,
            'title' => $this->title,
            'url' => $this->url
        ];
    }
}

Когда я удаляю «трансляцию» из массива via, все работает нормально. Я не знаю, что я делаю неправильно! Может кто-нибудь помочь, пожалуйста? Спасибо!

EDIT Вот моя полная трассировка стека

Stack trace:
  1. ErrorException->() /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:321
  2. array_key_exists() /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:321
  3. Illuminate\Database\Eloquent\Model->getAttribute() /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1396
  4. Illuminate\Database\Eloquent\Model->getKey() /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1406
  5. Illuminate\Database\Eloquent\Model->getQueueableId() /var/www/html/vendor/laravel/framework/src/Illuminate/Support/HigherOrderCollectionProxy.php:60
  6. Illuminate\Support\HigherOrderCollectionProxy->Illuminate\Support\{closure}() [internal]:0
  7. array_map() /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Collection.php:638
  8. Illuminate\Support\Collection->map() /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Collection.php:254
  9. Illuminate\Database\Eloquent\Collection->map() /var/www/html/vendor/laravel/framework/src/Illuminate/Support/HigherOrderCollectionProxy.php:61
 10. Illuminate\Support\HigherOrderCollectionProxy->__call() /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Collection.php:549
 11. Illuminate\Database\Eloquent\Collection->getQueueableIds() /var/www/html/vendor/laravel/framework/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php:25
 12. Illuminate\Notifications\Notification->getSerializedPropertyValue() /var/www/html/vendor/laravel/framework/src/Illuminate/Queue/SerializesModels.php:23
 13. Illuminate\Notifications\Notification->__sleep() [internal]:0
 14. serialize() /var/www/html/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:139
 15. Illuminate\Queue\Queue->createObjectPayload() /var/www/html/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:110
 16. Illuminate\Queue\Queue->createPayloadArray() /var/www/html/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:88
 17. Illuminate\Queue\Queue->createPayload() /var/www/html/vendor/laravel/framework/src/Illuminate/Queue/SyncQueue.php:40
 18. Illuminate\Queue\SyncQueue->push() /var/www/html/vendor/laravel/framework/src/Illuminate/Queue/Queue.php:44
 19. Illuminate\Queue\Queue->pushOn() /var/www/html/vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastManager.php:127
 20. Illuminate\Broadcasting\BroadcastManager->queue() /var/www/html/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:267
 21. Illuminate\Events\Dispatcher->broadcastEvent() /var/www/html/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php:190
 22. Illuminate\Events\Dispatcher->dispatch() /var/www/html/vendor/laravel/framework/src/Illuminate/Notifications/Channels/BroadcastChannel.php:51
 23. Illuminate\Notifications\Channels\BroadcastChannel->send() /var/www/html/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php:146
 24. Illuminate\Notifications\NotificationSender->sendToNotifiable() /var/www/html/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php:105
 25. Illuminate\Notifications\NotificationSender->Illuminate\Notifications\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Traits/Localizable.php:19
 26. Illuminate\Notifications\NotificationSender->withLocale() /var/www/html/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php:107
 27. Illuminate\Notifications\NotificationSender->sendNow() /var/www/html/vendor/laravel/framework/src/Illuminate/Notifications/NotificationSender.php:79
 28. Illuminate\Notifications\NotificationSender->send() /var/www/html/vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.php:39
 29. Illuminate\Notifications\ChannelManager->send() /var/www/html/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:261
 30. Illuminate\Support\Facades\Facade->__callStatic() /var/www/html/app/Http/Controllers/Basketball/BasketballGameController.php:458
 31. App\Http\Controllers\Basketball\BasketballGameController->updateJudges() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
 32. call_user_func_array() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Controller.php:54
 33. Illuminate\Routing\Controller->callAction() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:45
 34. Illuminate\Routing\ControllerDispatcher->dispatch() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php:219
 35. Illuminate\Routing\Route->runController() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Route.php:176
 36. Illuminate\Routing\Route->run() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php:681
 37. Illuminate\Routing\Router->Illuminate\Routing\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:130
 38. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php:43
 39. Illuminate\Auth\Middleware\Authenticate->handle() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171
 40. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/barryvdh/laravel-cors/src/HandleCors.php:58
 41. Barryvdh\Cors\HandleCors->handle() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171
 42. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php:41
 43. Illuminate\Routing\Middleware\SubstituteBindings->handle() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171
 44. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php:59
 45. Illuminate\Routing\Middleware\ThrottleRequests->handle() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171
 46. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:105
 47. Illuminate\Pipeline\Pipeline->then() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php:683
 48. Illuminate\Routing\Router->runRouteWithinStack() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php:658
 49. Illuminate\Routing\Router->runRoute() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php:624
 50. Illuminate\Routing\Router->dispatchToRoute() /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php:613
 51. Illuminate\Routing\Router->dispatch() /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:170
 52. Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:130
 53. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/fideloper/proxy/src/TrustProxies.php:57
 54. Fideloper\Proxy\TrustProxies->handle() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171
 55. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21
 56. Illuminate\Foundation\Http\Middleware\TransformsRequest->handle() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171
 57. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php:27
 58. Illuminate\Foundation\Http\Middleware\ValidatePostSize->handle() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171
 59. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php:62
 60. Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171
 61. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/barryvdh/laravel-cors/src/HandleCors.php:58
 62. Barryvdh\Cors\HandleCors->handle() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:171
 63. Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}() /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:105
 64. Illuminate\Pipeline\Pipeline->then() /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:145
 65. Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter() /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:110
 66. Illuminate\Foundation\Http\Kernel->handle() /var/www/html/public/index.php:55

ИЗМЕНИТЬ 2

В моем конструкторе моего уведомления у меня есть модель, использующая составной ключ. Как только я удаляю эту строку: $this->games = $games;, и редактирую $this->summary в какую-то строку - все работает! $gamesэто коллекция Модели Game.

Но я не знаю, почему это происходит?!


person Mike_NotGuilty    schedule 04.03.2020    source источник
comment
В сообщении об ошибке сообщается, в какой строке возникает ошибка, и предоставляется обратная трассировка до точки в пользовательском коде, где возникает ошибка.   -  person miken32    schedule 04.03.2020
comment
@ miken32 нет, потому что я хочу вернуть тот же массив, что и toArray()   -  person Mike_NotGuilty    schedule 05.03.2020
comment
Пожалуйста, поделитесь полным стеком ошибок   -  person Sehdev    schedule 05.03.2020
comment
@Sehdev Смотрите мое редактирование. Благодарю вас!   -  person Mike_NotGuilty    schedule 05.03.2020
comment
Попробуйте избавиться от use Queueable; и посмотрите, прояснится ли это. По крайней мере, это должно сделать трассировку короче. Если вы копируете это из отчета об исключении в своем браузере, он также должен показать вам параметры, которые были переданы array_key_exists, что может помочь вам выяснить проблему.   -  person miken32    schedule 06.03.2020
comment
@ miken32 где я могу найти параметры? Удаление use Queueable не дало результата. Все та же ошибка с той же трассировкой стека!   -  person Mike_NotGuilty    schedule 06.03.2020
comment
Я забыл, что Ignition больше не показывает аргументы функции, но если вы все еще используете Laravel 5, на странице ошибки Whoops должен отображаться список аргументов под кодом. Если бы ваше уведомление не было поставлено в очередь, я бы не ожидал увидеть Illuminate\Queue\Queue объектов в трассировке стека.   -  person miken32    schedule 06.03.2020
comment
Я удалил use Queueable, но он все еще показывает его в трассировке стека. Есть ли другое место, где я должен удалить его? Я использую Laravel 6.0 - моя страница с ошибкой выглядит так (пример): i.stack.imgur .com/YDQcV.png - но я не могу найти параметры   -  person Mike_NotGuilty    schedule 06.03.2020
comment
Аргумент в этом примере будет указан в разделе «Аргументы» и представляет собой строку «У вас нет разрешений».... Если вы видите, что такое аргумент для Illuminate\Database\Eloquent\Model->getAttribute(), вы можете понять, в чем проблема.   -  person miken32    schedule 06.03.2020
comment
Хорошо, я нашел причину ошибки, но я не знаю, почему это происходит! Пожалуйста, смотрите мое редактирование!   -  person Mike_NotGuilty    schedule 07.03.2020
comment
@ miken32 miken32 - я нашел решение своей проблемы, преобразовав Collection в массив перед передачей его в уведомление. Но нельзя ли это исправить, не конвертируя Collection?   -  person Mike_NotGuilty    schedule 07.03.2020


Ответы (1)


Если я правильно понимаю, причина в том, что ваша модель использует составной ключ, который не поддерживается красноречивый.

Итак, вот что, по моему мнению, на самом деле происходит с моими ограниченными знаниями обо всем модуле уведомлений/трансляций.

  1. Вы пытаетесь отправить свое уведомление, которое диспетчер затем передает вашему уведомлению диспетчеру вещания, поскольку вы указали его для вещания в своем методе via.
  2. Затем диспетчер вещания попытается поместить ваше событие MyNotification в очередь.
  3. Чтобы поместить событие в очередь, он попытается создать полезную нагрузку вашего класса уведомлений, который попытается его сериализовать.
  4. Базовый класс Notification, который вы расширяете, на самом деле реализует черту Illuminate\Queue\SerializesModels и поэтому автоматически попытается сериализовать всю модель в атрибутах вашего класса уведомлений.
  5. При попытке сериализовать вашу красноречивую коллекцию объектов Game коллекция затем пытается вызвать getQueueableId для каждой из ваших моделей в коллекции, что затем терпит неудачу, потому что она пытается получить атрибут на основе вашего составного ключа.

Что касается решения, я бы сказал, попробуйте удалить составной ключ на модели, так как кажется, что он не будет работать должным образом при использовании красноречия.

// in Game model
protected $primaryKey = 'id';

Согласно этой документации по очередям, вы также можете попробовать добавить метод broadcastWith в вашем классе MyNotification, хотя я не уверен, что это обойдет метод сериализации черты SerializeModels.

// in MyNotification
public function broadcastWith()
{
    return ['id' => $this->id];
}

Или в соответствии с вашими собственными пробами и ошибками вместо инициализации $this->games коллекцией вы можете преобразовать ее в массив. В конце концов, именно ваш метод toBroadcast фактически управляет трансляцией.

$this->games = $games->toArray();

И ваш последний вариант — переопределить метод getQueueableId() вашей модели Game.

// in Game Model
public function getQueueableId()
{
    return $this->id; 

    // or if you still want to utilize your composite keys. UNTESTED
    return $this->key_one.$this->key_two;
}
person Helioarch    schedule 11.03.2020
comment
Спасибо за совет getQueueableId()... который избавил меня от необходимости переписывать все на ->toArray() - person Mike_NotGuilty; 13.03.2020
comment
Привет @Mike_NotGuilty, тебе приходилось переопределять какие-либо другие методы, кроме getQueueableId()? А как ты $primaryKey на Game выглядишь? Это все еще массив имен столбцов? - person Daniel; 07.01.2021