Push notifications are essential for keeping users engaged with your app. Whether you're building a mobile app, web application, or both, OneSignal makes it easy to send notifications across platforms. In this guide, I'll show you how to integrate OneSignal into your Laravel application and start sending push notifications in minutes.
What You'll Learn
By the end of this tutorial, you'll know how to:
- Set up OneSignal in your Laravel application
- Send notifications to specific users
- Target user segments and groups
- Add images and action buttons to notifications
- Handle notification events
- Use Laravel's notification system with OneSignal
Prerequisites
Before we start, make sure you have:
- A Laravel 11 or 12 application
- PHP 8.3 or higher
- A OneSignal account (free tier works fine)
- Your OneSignal App ID and REST API Key
Step 1: Install the Package
First, install the OneSignal package via Composer:
composer require lepresk/laravel-onesignal
The package will auto-register with Laravel, so no need to manually add the service provider.
Step 2: Configure Your Credentials
Publish the configuration file:
php artisan vendor:publish --tag=onesignal-config
Add your OneSignal credentials to your .env file:
ONESIGNAL_APP_ID=your-app-id-here
ONESIGNAL_REST_API_KEY=your-rest-api-key-here
ONESIGNAL_ANDROID_CHANNEL_ID=your-android-channel-id
Getting Your OneSignal API Credentials
If this is your first time with OneSignal, here's how to get your credentials:
- Go to onesignal.com and create a free account
- Click New App/Website and follow the setup wizard
- Once your app is created, go to Settings in the left sidebar
- Click on Keys & IDs
- Copy your App ID and REST API Key
For the Android Channel ID:
- In your OneSignal dashboard, go to Settings → Platforms
- Under Android, you'll find your Firebase Server Key section
- The channel ID is typically something you define in your Android app (e.g., "default_channel")
- If you're only using iOS or web, you can leave this empty
Step 3: Send Your First Notification
Let's send a simple notification to test everything works:
use Lepresk\LaravelOnesignal\Facades\OneSignal;
use Lepresk\LaravelOnesignal\PushMessage;
$message = (new PushMessage())
->withTitle('Hello World')
->withBody('This is my first push notification!')
->toExternalUserIds([123]); // Your user's ID
$response = OneSignal::send($message);
if ($response->isSuccessful()) {
echo "Notification sent successfully!";
echo "Notification ID: " . $response->getNotificationId();
echo "Recipients: " . $response->getRecipients();
}
Understanding External User IDs
External User IDs are identifiers you assign to your users in OneSignal. They map your application's user IDs to OneSignal's internal player IDs. This way, you can send notifications to users using your own database IDs without tracking OneSignal's player IDs.
To set up external user IDs, you'll need to configure them in your mobile app or web SDK when users log in.
Step 4: Targeting Different Audiences
Send to Specific Users
// Single user
$message->toUser(123);
// Multiple users
$message->toExternalUserIds([1, 2, 3, 4, 5]);
Send to Segments
Segments are groups of users you define in your OneSignal dashboard based on criteria like location, language, or custom tags.
// Send to a custom segment
$message->toSegment('Premium Users');
// Send to multiple segments
$message->toSegments(['Premium Users', 'Active Users']);
// Built-in segments
$message->toSubscribedSegment(); // All subscribed users
$message->toActiveSegment(); // Active users
$message->toInactiveSegment(); // Inactive users
Send Based on Tags
Tags are key-value pairs you set on user devices for custom targeting:
$message->toTag('subscription_level', 'premium');
$message->toTag('age_group', '18-25');
$message->toTag('interests', 'technology', '=');
Step 5: Enhance Your Notifications
Add Images
Make your notifications stand out with images:
$message = (new PushMessage())
->withTitle('New Product Launch!')
->withBody('Check out our latest features')
->withImage('https://yourapp.com/images/product-launch.jpg')
->toSegment('All Users');
Add Action Buttons
Action buttons let users take immediate action from the notification:
$message = (new PushMessage())
->withTitle('Flash Sale!')
->withBody('50% off - 2 hours only')
->addButton('shop', 'Shop Now', 'https://yourapp.com/sale')
->addButton('remind', 'Remind Me Later')
->toSegment('Active Users');
The third parameter (URL) is optional. If provided, clicking the button will open that URL.
Multi-language Support
Send notifications in multiple languages:
$message = (new PushMessage())
->withTitle('Welcome!', 'en')
->withTitle('Bienvenue!', 'fr')
->withTitle('¡Bienvenido!', 'es')
->withBody('Thanks for joining our app', 'en')
->withBody('Merci de rejoindre notre application', 'fr')
->withBody('Gracias por unirte a nuestra aplicación', 'es')
->toSubscribedSegment();
Set Priority
Control how quickly users receive notifications:
// High priority (immediate delivery)
$message->withHightPriority();
// Normal priority
$message->withDefaultPriority();
Custom Data
Attach custom data to your notifications for handling in your app:
$message = (new PushMessage())
->withTitle('New Message')
->withBody('You have a new message from John')
->addData('type', 'chat')
->addData('chat_id', 456)
->addData('sender_id', 789)
->toUser($userId);
Step 6: Using Laravel's Notification System
For a more Laravel-native approach, integrate with Laravel's notification system:
Create a Notification
php artisan make:notification OrderShipped
Configure the Notification
<?php
namespace App\Notifications;
use Illuminate\Notifications\Notification;
use Lepresk\LaravelOnesignal\PushMessage;
class OrderShipped extends Notification
{
public function __construct(
private int $orderId,
private string $trackingNumber
) {}
public function via($notifiable): array
{
return ['push'];
}
public function toPush($notifiable): PushMessage
{
return (new PushMessage())
->withTitle('Order Shipped!')
->withBody("Your order #{$this->orderId} is on its way")
->addData('order_id', $this->orderId)
->addData('tracking_number', $this->trackingNumber)
->addButton('track', 'Track Order', "https://yourapp.com/orders/{$this->orderId}")
->toUser($notifiable->onesignal_id); // Assuming you store OneSignal user ID in this field
}
}
Send the Notification
$user = User::find(1);
$user->notify(new OrderShipped($orderId, $trackingNumber));
Step 7: Handle Notification Events
Monitor what happens with your notifications by listening to events:
// In your EventServiceProvider
use Lepresk\LaravelOnesignal\Events\NotificationSending;
use Lepresk\LaravelOnesignal\Events\NotificationSent;
use Lepresk\LaravelOnesignal\Events\NotificationFailed;
protected $listen = [
NotificationSending::class => [
LogNotificationAttempt::class,
],
NotificationSent::class => [
LogNotificationSuccess::class,
],
NotificationFailed::class => [
HandleNotificationFailure::class,
],
];
Example Event Listener
<?php
namespace App\Listeners;
use Lepresk\LaravelOnesignal\Events\NotificationSent;
use Illuminate\Support\Facades\Log;
class LogNotificationSuccess
{
public function handle(NotificationSent $event): void
{
Log::info('Push notification sent', [
'notification_id' => $event->response->getNotificationId(),
'recipients' => $event->response->getRecipients(),
]);
// Update your analytics, database, etc.
}
}
Step 8: Advanced Configuration
The package offers several configuration options in config/onesignal.php:
Set Default TTL (Time to Live)
Control how long OneSignal attempts to deliver notifications:
'defaults' => [
'ttl' => env('ONESIGNAL_DEFAULT_TTL', 604800), // 7 days
],
Configure Logging
'logging' => [
'enabled' => true,
'channel' => 'stack', // Use a specific log channel
'level' => 'info',
],
Exception Handling
'throw_exceptions' => true, // Throw exceptions on failures
If set to false, failures will be logged but won't throw exceptions.
Real-World Examples
Welcome New Users
$message = (new PushMessage())
->withTitle('Welcome to MyApp!')
->withBody('We\'re excited to have you here')
->withImage('https://myapp.com/welcome-banner.jpg')
->addButton('start', 'Get Started', 'https://myapp.com/onboarding')
->toUser($newUser->id);
OneSignal::send($message);
Cart Abandonment Reminder
$message = (new PushMessage())
->withTitle('Don\'t Forget Your Cart!')
->withBody('You left some items behind. Complete your order now.')
->addData('cart_id', $cart->id)
->addButton('checkout', 'Complete Purchase', 'https://myapp.com/checkout')
->setTTL(86400) // 24 hours
->toUser($user->id);
OneSignal::send($message);
Daily Digest for Active Users
$message = (new PushMessage())
->withTitle('Your Daily Digest')
->withBody('See what\'s new today')
->withImage('https://myapp.com/digest-banner.jpg')
->addButton('view', 'View Digest', 'https://myapp.com/digest')
->toActiveSegment()
->withDefaultPriority();
OneSignal::send($message);
Troubleshooting
Notification Not Received
- Verify your OneSignal credentials are correct
- Check that the user has a valid OneSignal player ID
- Ensure the user has granted notification permissions
- Check OneSignal dashboard for delivery status
Testing in Development
Use OneSignal's test mode and send to your own device first:
$message = (new PushMessage())
->withTitle('Test Notification')
->withBody('Testing push notifications')
->toUser($yourTestUserId);
$response = OneSignal::send($message);
dd($response->getRawResponse()); // See the full response
Common Pitfalls to Avoid
Sending too many notifications
I learned this the hard way. Users will disable notifications if you spam them. Be selective about what deserves a push notification.
Not testing on real devices
The OneSignal dashboard shows if a notification was sent, but only testing on actual devices tells you if it looks good and works properly.
Forgetting about timezones
Sending a promotion at 3 AM local time is not great. Use intelligent delivery or schedule based on user timezones.
Generic messages
"You have a new notification" tells users nothing. Be specific about what happened and why they should care.
Wrapping Up
That's it. You now have OneSignal working in your Laravel app with a clean, maintainable integration. The examples I showed cover most use cases, but there's more in the documentation if you need advanced features like delayed sending or custom notification sounds.
The package is open source, so if you run into issues or want to add features, contributions are welcome on GitHub.
Links:
- GitHub: https://github.com/lepresk/laravel-onesignal
- Packagist: https://packagist.org/packages/lepresk/laravel-onesignal
If you found this helpful or have questions, leave a comment. I'm usually pretty quick to respond.
Top comments (0)