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

Native Push Laravel Package

akyos/native-push

akyos/native-push is a Laravel package for sending native push notifications to mobile apps. It simplifies device token management and message delivery, making it easier to add iOS and Android push support to Laravel projects.

View on GitHub
Deep Wiki
Context7

Getting Started

  • composer require akyos/native-push, then publish and review the config (config/native-push.php) and run the package migrations — you need the push_devices table before anything sends.
  • Fill credentials per platform. iOS: key ID, team ID, bundle ID, path to the .p8, and the sandbox/production flag. Android: project ID plus the service-account JSON path. Both are optional and independent — start with whichever platform you can actually test on.
  • Validate before coding: php artisan native-push:check (credentials + connectivity) then php artisan native-push:test <device-token>. If check fails, nothing downstream matters.
  • Reading order for the source: config file → PushSubjectInterface / PushSubjectTrait → the Notifier transport → the devices controller and the native-push Stimulus controller.
  • First use case: transactional push to a logged-in recipient — "your order shipped" — sent through the Symfony Notifier using the native-push://default transport, with a url() so tapping opens the order page.

Implementation Patterns

  • Recipient = entity. Implement PushSubjectInterface and use PushSubjectTrait on your user/entity, then send via NotifierInterface:

    $notifier->send(
        new PushMessage('Order shipped', $user, url: route('orders.show', $order))
    );
    

    The trait supplies the recipient's registered PushDevices, so a user with three devices fans out without extra work.

  • Event-driven, always queued. Trigger from domain events (OrderShipped, MessageReceived) via listeners that dispatch a ShouldQueue job. The transport performs a blocking HTTP/2 call per message; a synchronous loop over 10k users in a request will time out. One job per user, chunk() the device list.

  • Registration flow. The shipped Stimulus controller calls POST /native-push/devices after permission is granted and DELETE on logout. Protect those routes with your auth middleware group — check what the package registers by default and override it if it's open. The controller handles the token, but you own the "when to register" UX.

  • Per-platform opt-in. With only iOS configured, filter devices by platform before sending rather than letting Android sends fail per-message. Same in reverse.

  • Operations surface. native-push:devices for auditing/cleanup, native-push:send for scheduled digests or one-off broadcasts from cron/Tinker, native-push:check in your deploy pipeline as a post-deploy smoke test.

  • Testing. Never hit APNs/FCM in CI. Bind a fake/null notifier transport in the test container and assert on dispatched messages/queued jobs; keep one manual native-push:test run per environment as the real integration check.

Gotchas and Tips

  • This is Doctrine-first. "Any Doctrine entity" means laravel-doctrine entities, not plain Eloquent models. If your app is Eloquent, read the trait before adopting — it expects a stable identifier and a device relation. Wrap or adapt rather than assuming it drops onto App\Models\User.
  • Dead-token deletion is destructive. APNs sandbox tokens sent to the production host return BadDeviceToken, which looks identical to a dead token. Confirm cleanup only fires on BadDeviceToken/410 Unregistered, never on 403, 429 or network errors — otherwise a wrong sandbox flag wipes your entire iOS device table in one send.
  • Sandbox vs production is the #1 support ticket. .p8 keys are shared, hosts are not. Dev builds and TestFlight behave differently. Verify which one you're on before debugging payloads.
  • FCM v1 is OAuth2. A rotated or expired service-account key surfaces as 401 with an unrelated-looking message; clock skew on the host can do the same. native-push:check catches it early — run it after every deploy that touches env.
  • Config caching. php artisan config:cache after env changes; check reads the cached config, so a stale cache makes credential debugging maddening.
  • url() needs app support. The deep link only works if the app was scaffolded with akyos/ux-native-cli --notification (or you implement the same payload key yourself). It also only fires on tap, never on delivery — don't use it as an analytics signal.
  • Payload limits. ~4 KB for APNs; long URLs plus a fat body get rejected. Keep the URL short and put the data in your API, not the notification.
  • CSRF/auth on the devices endpoint. A same-origin fetch from the Stimulus controller carries the session; a webview or separate origin gets 419/401. If you support multiple clients, consider a token-auth variant of the route.
  • Shared devices reattribute tokens. A family tablet will silently move its token to whoever logged in last. Decide whether logout should DELETE the device or let reattribution happen.
  • Success ≠ delivery. APNs/FCM accept-and-forget; a 200 and an apns-id/message name only mean "queued". Store those IDs for support, and don't build "user saw it" logic on the send result.
  • Extension points when the payload knobs run out (iOS content-available silent pushes, Android data-only messages, per-platform TTS/badge): decorate or subclass the Notifier transport, and swap the device storage behind the model/config if you need soft deletes or audit history.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect