Laravel 5.3 Send Notification to Users without an account
Asked Answered
A

6

13

With the Laravel 5.3 Notification feature, I see that the notifications are sent to users like this:

$user->notify(new InvoicePaid($invoice));

Where I believe $user is the notifiable entity. What if I want to send notifications to users who doesn't have an account yet? In my app, users send invitation to their friends to join. I am trying to use Laravel's Notification to send the invite code to users who don't have an account yet.

When users invite someone, their data is stored in Invite Model like this:

class Invite extends Model
  {
    protected $table = 'invites';
    protected $fillable = array('name', 'email', 'invite_code', 'expires_at', 'invited_by');
    protected $dates = ['expires_at'];
   }

I thought I can use notify to send notifications to the Invite model like this:

$invite = Invite::find($inviteId);
$invite->notify(new InvitationNotification(ucfirst($invite->name), $invite->invite_code, $invite->expires_at));  

But the above doesnt work. I get the error:

Call to undefined method Illuminate\Database\Query\Builder::notify()

So my question is:

  1. Am I able to send Notification only to User Model?

  2. Is there a way to send Notifications to new users who doesnt have an account yet?

  3. Is my only choice is to use Laravel's Mailable class instead of Notification in these cases?

Antibiotic answered 24/11, 2016 at 7:16 Comment(0)
G
16

I found your post looking for the same thing but answered it myself.

You need to use Notifiable; on the Invite model.

You then import use Illuminate\Notifications\Notifiable; and should be able to use ->notify on the Invite model.

$invite = Invite::create([
    'name' => $request->get('name'),
    'email' => $request->get('email'),
    'token' => str_random(60),
]);

$invite->notify(new UserInvite());

That is how I handle sending the notification :)

You can then pass through $invite and use that within the notification template.

Gladiatorial answered 27/11, 2016 at 12:5 Comment(0)
G
16

Some alternative solution could be to just new up a user model and set the email attribute without saving it. The instance can now be notified.

I don't see this as the correct approach for this particular case, but for the questions written and since this thread provides some different ways to notify a non-existing user I thought I would write it here.

$invitedUser = new User;
$invitedUser->email = '[email protected]';
$invitedUser->notify(new InvitationNotification());

Beware, that this solution may cause problems when queueing notification (because it doesn't reference a specific user id).

In Laravel >=5.5 it is possible to make an "on-demand notification", which covers this exact case, where you want to notify a non-existing user.

Example from the docs:

Notification::route('mail', '[email protected]')
        ->route('nexmo', '5555555555')
        ->notify(new InvoicePaid($invoice));

This will send the notification to the email address, and that approach can be queued etc.

The docs: https://laravel.com/docs/5.5/notifications#on-demand-notifications

Geilich answered 19/2, 2019 at 8:3 Comment(0)
S
3

Notifications are meant to be sent to a notifiable object. You don’t “notify” an invitation.

If all you’re wanting to do is email someone that they’ve been invited to use an application, then just send an email to that email address. Notifications aren’t appropriate in this instance.

Signe answered 1/12, 2016 at 21:38 Comment(5)
Thank you @martin. Logically this does make sense. The only reason I was trying to use the notification is due to the ease in using the standard email template for both text and html and adding a database entry for that. But yeah, I do understand that mailable classes is probably more appropriate in the sense that this isint really a user notification.Antibiotic
You can make the Invite model to be notifiableRealism
@Realism But does it make sense to…? Do you notify an invite? Or the recipient or an invite?Signe
You can make any model notifiable - I don't believe that you should be restricted to just "notifying" users. Although, in this case, if you do have an "Invitation" model, then it's worth to rethink that this model would most certainly have a "user" of some sort attached to it. In that case, you can do $invitation->user->notify(new WhateverNotification)Realism
@Realism Yes. That’s why I said you’d most likely notify the recipient of an invite, and not just “notify” the invite itself. Which makes no sense.Signe
C
2

I had similar issue and I was able to get around it by using an instance of \Illuminate\Notifications\AnonymousNotifiable. This object gets serialized and does not require any DB infrastructure and works with queuing.

$anonymousNotifiable = new AnonymousNotifiable();
$anonymousNotifiable->route('mail', ['[email protected]' => 'Scott Tiger']);
$anonymousNotifiable->notify(new NotificationExample());

You can also call the static function route on class \Illuminate\Support\Facades\Notification which returns an instance of AnonymousNotifiable:

Notification::route('mail', ['[email protected]' => 'Scott Tiger'])->notify(new NotificationExample());
Choose answered 20/10, 2020 at 7:28 Comment(1)
This should be the accepted answer. It is much safer and cleaner to use an AnonymousNotifiable than to create a fake User model and not persist it.Commissary
V
1

I just figured out a simpler way to this. First you have to override the 'register' function in your RegisterController class. In order to do that:

use Illuminate\Http\Request;
use Illuminate\Auth\Events\Registered;

public function register(Request $request)
{


}

Then add these lines in your register function;

  1. $user = $this->create($request->all()); //To create and save the user
  2. $user->notify(new NewRegistrationNotification($request)); //To call the specified notification class
  3. return redirect()->to('/')->with('msg', 'Thanks for registering! Check your inbox for the activation link');

Next, configure your Notification class to handle the message send. I did something like this in my constructor;

protected $data;

public function __construct(Request $request)
{
     $this->data = $request;
}

I hope this helps somebody.

Vesture answered 22/4, 2017 at 14:2 Comment(2)
Yeah, but in 1 you are creating a User which is the notifiable object. But my original question was to send notification to users who are not created at all. Thanks for your input though.Antibiotic
How about creating an anonymous user in your app. Then any time you want to send an invite using notifications, you instantiate and the 'anonymous' instance. I believe the destination mail can be configured to your target destination email address. Sorry I haven't tried it out yet reason there is no code attached. Let me know if you still need me to test out.Vesture
R
0

In Laravel 5.5 and above you can now use on demand notification, add the following code snippet to your controller or observer

Notification::route('mail', '[email protected]')->notify(new InvoicePaid($invoice))

route('mail', '[email protected]') means use the mail channel and use [email protected] as the to-email

Don't forget to import Illuminate\Support\Facades\Notification

Repand answered 8/7, 2021 at 7:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.