Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CouldNotSendNotification thrown even when notification was sent successfully #4

Open
tusharvikky opened this issue May 13, 2017 · 25 comments

Comments

@tusharvikky
Copy link

Hello,

"Notification was not sent. You should specify device token(s), topic(s) or group(s) for sending notification."

However, laravel-fcm.log logs
[2017-05-13 20:37:29] Laravel-FCM.INFO: notification send to 1 devices success: 1 failures: 0 number of modified token : 0 [] [] and the push notification was successfully delivered.

@enniel
Copy link
Owner

enniel commented May 15, 2017

show your code in routeNotificationForFCM

@tusharvikky
Copy link
Author

@enniel It has a comma separated list of tokens. Any info if you have to sent notification to n devices of a single user?

@tusharvikky
Copy link
Author

Any update?

@enniel
Copy link
Owner

enniel commented May 17, 2017

Show your code in routeNotificationForFCM and your notification file. I need to test your code.

@tusharvikky
Copy link
Author

    public function routeNotificationForFcm()
    {
        $tokens = implode(",", PushToken::where('user_id', $this->id)->pluck('token')->toArray());
        return $tokens;
    } 

Notification File:

<?php

namespace App\Notifications;

use App\Models\PushToken;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use NotificationChannels\FCM\FCMMessage;


class ClassroomCreated extends Notification implements ShouldQueue
{
    use Queueable;

    private $classroom;
    private $tokens;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($classroom)
    {
        $this->classroom = $classroom;
    }

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

    public function toFCM($notifiable)
    {
        try {
            // dd($this->classroom);
            $message = Config::get('gb.notification_messages.classroom');
            $rand_message = $message[array_rand($message, 1)];
            return (new FCMMessage())
                // ->to( $this->tokens )
                ->notification([
                    'title' => $rand_message,
                    'body' => $this->classroom->name,
                    'clickAction' => $this->classroom->id
                ]);            
        } catch (\Exception $e) {
                // dd($e);
            Log::error($e);
        }

    }

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

@enniel
Copy link
Owner

enniel commented May 17, 2017

You tryed array of tokens?

    public function routeNotificationForFCM()
    {
        return PushToken::where('user_id', $this->id)->pluck('token')->toArray();
    } 

@tusharvikky
Copy link
Author

Sadly, that didn't help either.

[2017-05-17 19:29:36] local.ERROR: exception 'NotificationChannels\FCM\Exceptions\CouldNotSendNotification' with message 'Notification was not sent. You should specify device token(s), topic(s) or group(s) for sending notification.' in /<project>/vendor/enniel/laravel-fcm-notification-channel/src/Exceptions/CouldNotSendNotification.php:14

@enniel
Copy link
Owner

enniel commented May 17, 2017

You used routeNotificationForFCM or routeNotificationForFcm method?

@tusharvikky
Copy link
Author

Tried w/ both. Didn't work. Still the same.

@enniel
Copy link
Owner

enniel commented May 17, 2017

You can show output from dd(PushToken::where('user_id', $this->id)->pluck('token')->toArray()) ?

@tusharvikky
Copy link
Author

image

@enniel
Copy link
Owner

enniel commented May 17, 2017

I'm tried send notification and all works:

// notifiable model
<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];


    public function routeNotificationForFCM() {
      return ['fYuuanS_YK4:APA91bEsFBKF3cUXotoxvOv2S9kyss9V3ONQZUuDq8cBvm57AuXdJn6SB3sY5JMpe0lLJUPk4D7c8bWTtPLRkwykJNtnazNMmBbo8eoU8mctiTZXf5XvN_lA_h7Mf9o2AUg9gMBgfmKG'];
    }
}
// notification
<?php

namespace App\Notifications;

use NotificationChannels\FCM\FCMMessage;
use Illuminate\Notifications\Notification;

class ExampleNotification extends Notification
{
    public function via($notifiable)
    {
        return ['fcm'];
    }

    public function toFCM($notifiable)
    {
        return (new FCMMessage())
            ->notification([
                'title' => 'Notification title',
                'body' => 'Notification body',
            ]);
    }
}
// send notififications
Notification::send(User::all(), new ExampleNotification());

@tusharvikky
Copy link
Author

This is so weird. Only two things different is queue able and that try catch block.

@enniel
Copy link
Owner

enniel commented May 18, 2017

Maybe

    public function routeNotificationForFCM() {
      return PushToken::where('user_id', $this->id)->whereNotNull('token')->pluck('token')->toArray();
    }

@enniel
Copy link
Owner

enniel commented May 18, 2017

You can show your notifiable model code?

@tusharvikky
Copy link
Author

tusharvikky commented May 18, 2017

Its mostly the same as you have. However, I'm initiating the notification in model boot function.

class Classroom extends Model
{
	use BelongsToTenants;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $guarded = ['id'];
    public $tenantColumns = ['team_id'];

    public static function boot()
    {
        parent::boot();

        // self::creating(function($model){
        //     // ... code here
        // });

        self::created(function($model){
            // Send notification to all User who are member of this team.
            $user_ids = TeamUser::where('team_id', $model->team_id)->pluck('user_id');
            $users = User::whereIn('id', $user_ids)->get();
            // $model->notify(new ClassroomCreated($model));
            Notification::send($users, new ClassroomCreated($model));
        });

        // self::updating(function($model){
        //     // ... code here
        // });

        // self::updated(function($model){
        //     // ... code here
        // });

        // self::deleting(function($model){
        //     // ... code here
        // });

        // self::deleted(function($model){
        //     // ... code here
        // });
    }

@enniel
Copy link
Owner

enniel commented May 19, 2017

Show please User model

@tusharvikky
Copy link
Author

<?php

namespace App\Models;

use App\Models\PushToken;
use App\Models\Role;
use App\Models\Team;
use App\Notifications\ResetPassword;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name', 'email', 'password', 'username'];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];

    /**
     * Find by Email
     *
     * @param  string $email
     * @return User
     */
    public function findByEmail($email)
    {
        return $this->where('email', $email)->first();
    }

    /**
     * Send the password reset notification.
     *
     * @param  string  $token
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new ResetPassword($token));
    }

    /**
     * Get the user's first name.
     *
     * @param  string  $value
     * @return string
     */
    public function getNameAttribute($value)
    {
        return ucfirst($value);
    } 

    /**
     * Route notifications for the mail channel.
     *
     * @return string
     */
    public function routeNotificationForFcm()
    {
        $tokens = implode(",", PushToken::where('user_id', $this->id)->pluck('token')->toArray());
        return $tokens;
    } 

    public function routeNotificationForOneSignal()
    {
        $player_ids = implode(",", PushToken::where('user_id', $this->id)->pluck('player_id')->toArray());
        return $player_ids;
    }          
}

@enniel
Copy link
Owner

enniel commented May 19, 2017

    public function routeNotificationForFCM()
    {
        return PushToken::where('user_id', $this->id)->pluck('token')->toArray();
    }

@tusharvikky
Copy link
Author

tusharvikky commented May 19, 2017 via email

@tusharvikky
Copy link
Author

tusharvikky commented May 20, 2017

namespace App\Models;

use App\Models\PushToken;
use App\Models\Role;
use App\Models\Team;
use App\Models\UserMeta;
use App\Notifications\ResetPassword;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    /**
     * The database table used by the model.
     *
     * @var string
     */
    protected $table = 'users';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name', 'email', 'password', 'username'];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = ['password', 'remember_token'];

    /**
     * The relations to eager load on every query.
     *
     * @var array
     */
    protected $with = ['roles', 'teams'];

    /**
     * User UserMeta
     *
     * @return Relationship
     */
    public function meta()
    {
        return $this->hasOne(UserMeta::class);
    }

    /**
     * User Roles
     *
     * @return Relationship
     */
    public function roles()
    {
        return $this->belongsToMany(Role::class);
    }

    /**
     * Check if user has role
     *
     * @param  string  $role
     * @return boolean
     */
    public function hasRole($role)
    {
        $roles = array_column($this->roles->toArray(), 'name');
        return array_search($role, $roles) > -1;
    }

    /**
     * Teams
     *
     * @return Relationship
     */
    public function teams()
    {
        return $this->belongsToMany(Team::class);
    }

    /**
     * Team member
     *
     * @return boolean
     */
    public function isTeamMember($id)
    {
        $teams = array_column($this->teams->toArray(), 'id');
        return array_search($id, $teams) > -1;
    }

    /**
     * Team admin
     *
     * @return boolean
     */
    public function isTeamAdmin($id)
    {
        $team = $this->teams->find($id);
        if ($team) {
            return (int) $team->user_id === (int) $this->id;
        }
        return false;
    }

    /**
     * Find by Email
     *
     * @param  string $email
     * @return User
     */
    public function findByEmail($email)
    {
        return $this->where('email', $email)->first();
    }

    /**
     * Send the password reset notification.
     *
     * @param  string  $token
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new ResetPassword($token));
    }

    /**
     * Get the user's first name.
     *
     * @param  string  $value
     * @return string
     */
    public function getNameAttribute($value)
    {
        return ucfirst($value);
    } 

    /**
     * Route notifications for the mail channel.
     *
     * @return string
     */
    public function routeNotificationForFCM()
    {
        // $tokens = implode(",", PushToken::where('user_id', $this->id)->pluck('token')->toArray());
        // dd(PushToken::where('user_id', $this->id)->pluck('token')->toArray());
        return PushToken::where('user_id', $this->id)->whereNotNull('token')->pluck('token')->toArray();
    } 
}

@tusharvikky
Copy link
Author

@enniel Any update?

@tusharvikky
Copy link
Author

Could you please try with this code:

    public function routeNotificationForFCM() {
      return [ 0 => 'fYuuanS_YK4:APA91bEsFBKF3cUXotoxvOv2S9kyss9V3ONQZUuDq8cBvm57AuXdJn6SB3sY5JMpe0lLJUPk4D7c8bWTtPLRkwykJNtnazNMmBbo8eoU8mctiTZXf5XvN_lA_h7Mf9o2AUg9gMBgfmKG'];
    }

@bayuly94
Copy link

image
how to solve it ?
i hope add exception and delete failed token

@promatik
Copy link

@bayuly94 have you solved your issue? How?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants