Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Expo Notifier Laravel Package

yieldstudio/laravel-expo-notifier

Send push notifications to Expo (React Native) apps from Laravel with a clean, fluent API. Manage Expo push tokens, send notifications to one or many devices, and integrate with Laravel's notification system.

View on GitHub
Deep Wiki
Context7

Getting Started

0.0.17 is a small maintenance release that updates ExpoMessage.php; no breaking changes or new features are called out in the release notes. Treat the package as early 0.0.x software and pin versions in production.

Minimal setup:

composer require yieldstudio/laravel-expo-notifier
php artisan vendor:publish --provider="YieldStudio\LaravelExpoNotifier\LaravelExpoNotifierServiceProvider"
php artisan migrate
  1. Publish the package config and migrations, then run migrations for the Expo token table.
  2. Add the package’s Expo-token trait to your User model or other notifiable model so it can own multiple device tokens.
  3. Register the mobile device’s Expo push token from your app after login or permission grant.
  4. Create a Laravel notification using the package’s Expo channel and toExpo() method, then send it like any other Laravel notification.

First practical use case: store one Expo token per device for each user, then send a queued notification to all of that user’s devices.

Look first at:

  • The package README for exact publish tags, trait name, and channel usage.
  • config/expo-notifier.php for credentials and defaults.
  • The published migration and ExpoToken model for token storage.
  • ExpoMessage for supported message fields such as title, body, data, sound, badge, and channel ID.
  • ExpoChannel for how Laravel notifications are converted into Expo requests.

Implementation Patterns

Use Laravel notifications as the default path. Create notification classes with via() returning the Expo channel and toExpo() returning an ExpoMessage. This keeps push notifications consistent with mail, database, and broadcast notifications.

public function via($notifiable)
{
    return [ExpoChannel::class];
}

public function toExpo($notifiable)
{
    return (new ExpoMessage())
        ->setTitle('Order shipped')
        ->setBody('Your order is on the way.')
        ->setData(['order_id' => $this->order->id]);
}

Queue push sends. Implement ShouldQueue on notification classes or dispatch them from jobs. Avoid sending Expo requests inline in web requests, especially when notifying many devices.

Model device tokens explicitly. Treat Expo tokens as device records, not user attributes. A user may have several devices, tokens rotate, and old tokens become invalid. Store metadata such as platform, device name, last seen, and created time if you need operational visibility.

Register and refresh tokens on mobile login. Have the app send the current Expo token after login and on token refresh. Upsert by token rather than blindly creating duplicates.

Send to one user, a token, or a batch. Use notification classes for user-facing flows, and direct message sends for targeted/transactional cases when you already have a token. For large audiences, chunk recipients and dispatch jobs rather than building one giant request.

Test with Laravel’s notification fakes. Use Notification::fake() to assert notifications are sent, and unit-test your ExpoMessage payloads separately. For integration testing, use Expo’s push notification tooling or a test token rather than relying on production devices.

Handle channel configuration for Android. If your app uses Android notification channels, include the correct channelId in the Expo message and ensure the channel exists in the mobile app.

Gotchas and Tips

  • Receipts are not final delivery. Expo returns tickets; delivery errors such as invalid or unregistered tokens often appear later in receipts. Plan to check receipts and delete tokens that Expo reports as DeviceNotRegistered.
  • Tokens rotate. Re-register tokens whenever the mobile app receives a new one. Do not assume a token is permanent.
  • Avoid duplicate tokens. Add a unique constraint or application-level upsert for Expo tokens, but account for the same token moving between users after logout/login.
  • Payload size matters. Expo data payloads are limited. Keep data small, JSON-serializable, and free of models or large blobs.
  • Queue workers need restarts after config changes. If you change package config or credentials, restart queue workers and clear cached config with php artisan config:clear.
  • 0.0.x API instability. The 0.0.17 change is limited to ExpoMessage.php, but early package versions can change message-builder behavior. Pin the version and review the diff when upgrading.
  • Credentials live mostly in Expo. Laravel sends the push request, but iOS/Android push credentials, APNs/FCM setup, and app permissions are configured in Expo and the mobile app.
  • Log failures without leaking tokens. Expo tokens are identifiers, but avoid dumping full payloads and tokens in production logs.
  • Use batching and backoff. For many notifications, chunk sends, queue them, and use retries/backoff for transient Expo API failures.
  • Extension point: wrap message construction in your own notification base class or helper if you need consistent defaults for sound, badge, channel ID, and data shape across the app.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource