title: Laravel event with socket-io [receive notifications]
body: <p>For the first time attempt with <code>laravel</code> and <code>socket-io</code> I am trying to send very simple notification to admins. <strong>So far my event is firing but I need help with receiving event notifications</strong>.</p>
  
  <h1>Logic</h1>
  
  <p><em>It's very basic because I want to understand the process.</em></p>
  
  <ol>
  <li>User opens page <code>Add Product</code></li>
  <li>Admin gets notification that <code>user X</code> is in <code>App Product</code> page.</li>
  </ol>
  
  <p><strong>So far</strong></p>
  
  <p>So far I can fire event and get user data (user that is in <code>Add Product</code> page)</p>
  
  <p><strong>Need help for</strong></p>
  
  <p>I need help to understand the way that admin receives notifications.</p>
  
  <h1>Code</h1>
  
  <p>Component script</p>
  
  <pre><code>created() {
    let user = JSON.parse(localStorage.getItem("user"))
    this.listenForBroadcast(user);
  },
  methods: {
    listenForBroadcast(user) {
      Echo.join('userInAddProduct')
      .here((Loggeduser) =&gt; {
        console.log('My user data', Loggeduser);
      });
    }
  }
  </code></pre>
  
  <p><strong>Result of code above</strong></p>
  
  <pre><code>My user data [{…}]
    0:
      id: 1
      name: "Test User"
      photo: "User-1588137335.png"
      __ob__: Observer {value: {…}, dep: Dep, vmCount: 0}
      get id: ƒ reactiveGetter()
      set id: ƒ reactiveSetter(newVal)
      get name: ƒ reactiveGetter()
      set name: ƒ reactiveSetter(newVal)
      get photo: ƒ reactiveGetter()
      set photo: ƒ reactiveSetter(newVal)
      __proto__: Object
      length: 1
      __proto__: Array(0)
  </code></pre>
  
  <p>Channels route</p>
  
  <pre><code>Broadcast::channel('userInAddProduct', function ($user) {
      return [
          'id' =&gt; $user-&gt;id,
          'photo' =&gt; $user-&gt;photo,
          'name' =&gt; $user-&gt;name
      ];
  });
  </code></pre>
  
  <p>MessagePushed (event file)</p>
  
  <pre><code>class MessagePushed implements ShouldBroadcast
  {
      use Dispatchable, InteractsWithSockets, SerializesModels;
  
      public $user;
  
      public function __construct(User $user)
      {
          $this-&gt;user = $user;
      }
  
      public function broadcastOn()
      {
          return new PresenceChannel('userInAddProduct');
      }
  }
  </code></pre>
  
  <p><strong>Question</strong></p>
  
  <p>How can I receive notification about this event fire? I want to notify my admin users that <code>user x</code> is in page <code>Add Product</code>?</p>
  
  <h1>Update</h1>
  
  <p>Since I published this question I've made some changes and here is my latest code + questions.</p>
  
  <p><code>bootstrap.js</code></p>
  
  <pre><code>window.io = require('socket.io-client');
  
  window.Echo = new Echo({
      broadcaster: 'socket.io',
      host: window.location.hostname + ':6001',
      auth: { // added authentication token (because all my events are private)
          headers: {
              Authorization: localStorage.getItem('access_token'),
          },
      },
  });
  </code></pre>
  
  <p><code>Add.vue (add product component where event has to be fired)</code></p>
  
  <pre><code>listenForBroadcast(user) {
      let ui = JSON.parse(localStorage.getItem("user"))
      Echo.join('userInAddProduct')
      .here((users) =&gt; {
          console.log('My user data', users)
      })
      .joining((user) =&gt; {
          this.$notify({
              title: '',
              message: user + 'joining',
              offset: 100,
              type: 'success'
          });
      })
      .leaving((user) =&gt; {
          this.$notify({
              title: '',
              message: user + 'is leaving new product',
              offset: 100,
              type: 'warning'
          });
      })
      .whisper('typing', (e) =&gt; {
          this.$notify({
              title: '',
              message: ui.username + 'is adding new product',
              offset: 100,
              type: 'success'
          })
      })
      .listenForWhisper('typing', (e) =&gt; {
          console.log(e)
          this.$notify({
              title: '',
              message: ui.username + 'is entered add new product page.',
              offset: 100,
              type: 'success'
          });
      })
      .notification((notification) =&gt; {
          console.log('noitication listener: ', notification.type);
      });
  },
  </code></pre>
  
  <p>Then I've made 4 files to handle events:</p>
  
  <ul>
  <li>Event (<code>passing data</code>)</li>
  <li>Event Listener (<code>process the database storage</code> and <code>showing notifications</code> to online admins)</li>
  <li>Observer (firing event)</li>
  <li>Notification (<code>store data to database</code> for admins in case when event fire they're not online so they can see notifications later on)</li>
  </ul>
  
  <p><code>Event file</code></p>
  
  <pre><code>class MessagePushed extends Event implements ShouldBroadcast
  {
      use Dispatchable, InteractsWithSockets, SerializesModels;
  
      public $user;
      public $product;
  
      public function __construct(User $user, Product $product)
      {
          $this-&gt;user = $user;
          $this-&gt;product = $product;
      }
  
      public function broadcastOn()
      {
          return new PresenceChannel('userInAddProduct');
      }
  }
  </code></pre>
  
  <p><code>Listener file</code></p>
  
  <pre><code>class ThingToDoAfterEventWasFired implements ShouldQueue
  {
      public function handle(MessagePushed $event)
      {
          //Log testing purpose only
          $user = $event-&gt;user-&gt;username;
          $product = $event-&gt;product-&gt;name;
  
          // Real data that should be broadcasts
          $user2 = $event-&gt;user;
          $product2 = $event-&gt;product;
  
          // inform all admins and authorized staffs about new product
          $admins = User::role(['admin', 'staff'])-&gt;get();
          foreach($admins as $admin) {
              $admin-&gt;notify(new UserAddProduct($user2, $product2));
          }
  
          Log::info("Product $product was Created, by worker: $user");
      }
  }
  </code></pre>
  
  <p><code>Notification</code></p>
  
  <pre><code>class UserAddProduct extends Notification implements ShouldQueue
  {
      use Queueable;
  
      protected $product;
      protected $user;
  
      public function __construct(User $user, Product $product)
      {
          $this-&gt;product = $product;
          $this-&gt;user = $user;
      }
  
      public function via($notifiable)
      {
          return ['database', 'broadcast'];
      }
  
      public function toDatabase($notifiable)
      {
          return [
              'user_id' =&gt; $this-&gt;user-&gt;id,
              'user_username' =&gt; $this-&gt;user-&gt;username,
              'product_id' =&gt; $this-&gt;product-&gt;id,
              'product_name' =&gt; $this-&gt;product-&gt;name,
          ];
      }
  
      public function toArray($notifiable)
      {
          return [
              'id' =&gt; $this-&gt;id,
              'read_at' =&gt; null,
              'data' =&gt; [
                  'user_id' =&gt; $this-&gt;user-&gt;id,
                  'user_username' =&gt; $this-&gt;user-&gt;username,
                  'product_id' =&gt; $this-&gt;product-&gt;id,
                  'product_name' =&gt; $this-&gt;product-&gt;name,
              ],
          ];
      }
  }
  </code></pre>
  
  <p><code>Observer</code></p>
  
  <pre><code>public function created(Product $product)
  {
      $user = Auth::user();
      event(new MessagePushed($user, $product));
  }
  </code></pre>
  
  <h3>Questions</h3>
  
  <ol>
  <li>How can I return live notifications as soon as event is fired <strong>in whole app</strong>? currently as my code is placed in <code>add.vue component admins get notify IF they are in same page only :/</code></li>
  <li>How do I get notifications of multiple event? let say I have another <code>event, listener, observer</code> for other page actions I want admin be notified of both <code>product event</code> and <code>other event</code> in whole app.</li>
  </ol>
  
  <p>thanks</p>