ankurk91 / fcm-notification-channel
Firebase推送通知通道,适用于Laravel
2.1.0
2024-03-15 04:46 UTC
Requires
- php: ^8.2
- illuminate/events: ^10.0 || ^11.0
- illuminate/notifications: ^10.0 || ^11.0
- illuminate/support: ^10.0 || ^11.0
- kreait/firebase-php: ^7.5
- kreait/laravel-firebase: ^5.2
Requires (Dev)
- orchestra/testbench: ^8.0 || ^9.0
- phpunit/phpunit: ^9.5 || ^10.0
- roave/better-reflection: ^6.0
README
使用Laravel PHP框架发送Firebase推送通知。
亮点
- 使用最新的Firebase HTTP v1 API
- 向主题或条件发送消息
- 向特定设备或多个设备(多播)发送消息
- 与通知一起发送附加的RAW数据
- 支持单个Laravel应用程序中的多个Firebase项目:fire
- 使用事件和监听器处理无效令牌
- 经过充分测试的包,包含自动测试用例
- 由经过战斗考验的Firebase php SDK 🚀提供支持
安装
您可以通过composer安装此包
composer require "ankurk91/fcm-notification-channel"
配置
此包依赖于laravel-firebase包以与Firebase服务交互。以下是在您的.env
文件中需要的最小配置
# relative or full path to the Service Account JSON file FIREBASE_CREDENTIALS=firebase-credentials.json
您需要创建一个服务帐户并将JSON文件放置在项目根目录中。
此外,您可以更新您的.gitignore
文件
/firebase-credentials*.json
使用方法
您可以在通知类中的via()
方法中使用FCM通道
<?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; use Illuminate\Contracts\Queue\ShouldQueue; use NotificationChannels\FCM\FCMChannel; use Kreait\Firebase\Messaging\CloudMessage; class ExampleNotification extends Notification implements ShouldQueue { use Queueable; public function via($notifiable): array { return [FCMChannel::class]; } public function toFCM($notifiable): CloudMessage { return CloudMessage::new() ->withDefaultSounds() ->withNotification([ 'title' => 'Order shipped', 'body' => 'Your order for laptop is shipped.', ]) ->withData([ 'orderId' => '#123' ]); } }
准备您的可通知模型
<?php namespace App\Models; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class User extends Authenticatable { use Notifiable; /** * Assuming that you have a database table which stores device tokens. */ public function deviceTokens(): HasMany { return $this->hasMany(DeviceToken::class); } public function routeNotificationForFCM($notification): string|array|null { return $this->deviceTokens->pluck('token')->toArray(); } /** * Optional method to determine which message target to use * We will use TOKEN type when not specified * @see \Kreait\Firebase\Messaging\MessageTarget::TYPES */ public function routeNotificationForFCMTargetType($notification): ?string { return \Kreait\Firebase\Messaging\MessageTarget::TOKEN; } /** * Optional method to determine which Firebase project to use * We will use default project when not specified */ public function routeNotificationForFCMProject($notification): ?string { return config('firebase.default'); } }
向主题或条件发送消息
此包不仅限于向令牌发送通知。
您可以使用Laravel的按需通知向主题或条件或多个令牌发送推送通知。
<?php use Illuminate\Support\Facades\Notification; use Kreait\Firebase\Messaging\MessageTarget; use App\Notification\ExampleNotification; Notification::route('FCM', 'topicA') ->route('FCMTargetType', MessageTarget::TOPIC) ->notify(new ExampleNotification()); Notification::route('FCM', "'TopicA' in topics") ->route('FCMTargetType', MessageTarget::CONDITION) ->notify(new ExampleNotification()); Notification::route('FCM', ['token_1', 'token_2']) ->route('FCMTargetType', MessageTarget::TOKEN) ->notify(new ExampleNotification());
事件
您可以消费Laravel内置的通知事件
<?php namespace App\Providers; use Illuminate\Notifications\Events; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; class EventServiceProvider extends ServiceProvider { protected $listen = [ Events\NotificationSent::class => [ //\App\Listeners\FCMNotificationSent::class, ], Events\NotificationFailed::class => [ \App\Listeners\FCMNotificationFailed::class, ], ]; }
以下为失败的监听器类示例
<?php namespace App\Listeners; use App\Models\User; use Illuminate\Support\Arr; use NotificationChannels\FCM\FCMChannel; use Illuminate\Contracts\Queue\ShouldQueue; use Kreait\Laravel\Firebase\Facades\Firebase; use Illuminate\Notifications\Events\NotificationFailed; class FCMNotificationFailed implements ShouldQueue { public function handle(NotificationFailed $event) { if ($event->channel !== FCMChannel::class) { return; } /** @var User $user */ $user = $event->notifiable; $invalidTokens = $this->findInvalidTokens($user); if (count($invalidTokens)) { $user->deviceTokens()->whereIn('token', $invalidTokens)->delete(); } } protected function findInvalidTokens(User $user): array { $tokens = Arr::wrap($user->routeNotificationFor('FCM')); if (! count($tokens)) { return []; } $project = $user->routeNotificationFor('FCMProject'); $response = Firebase::project($project)->messaging()->validateRegistrationTokens($tokens); return array_unique(array_merge($response['invalid'], $response['unknown'])); } }
有关验证设备令牌的更多信息,请参阅此处
然后;您可能希望在您的app/Exceptions/Handler.php
中忽略此异常
protected $dontReport = [ \NotificationChannels\FCM\Exception\InvalidRecipientException::class, ];
变更日志
请参阅CHANGELOG以获取有关最近更改的更多信息。
测试
composer test
安全性
如果您发现任何安全问题,请通过电子邮件pro.ankurk1[at]gmail[dot]com
报告,而不是使用问题跟踪器。
归属
此包基于此被拒绝的PR
许可证
此包根据MIT许可证授权。