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

Unified Push Laravel Package

zbox/unified-push

Unified push notification package for Laravel that sends messages through multiple providers behind one clean API. Configure your drivers, target devices or topics, and deliver consistent push notifications without rewriting provider-specific code.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Treat the source as the documentation. With 14 stars and zero dependents, assume the README is thin and the real contract lives in src/. Open composer.json first and check the illuminate/* and php constraints — a 2016 release will target Laravel 5.2/5.3-era APIs and PHP 5.6/7.0. Verify it will actually install against your app before planning around it.
  • Register the service provider manually unless extra.laravel in composer.json declares discovery. In a legacy config/app.php, add the provider under providers and any facade under aliases. Then publish the config (php artisan vendor:publish --provider="Zbox\UnifiedPush\...ServiceProvider") and read every key: APNS certificate path/passphrase and sandbox flag, GCM API key, MPNS credentials, and any default driver selection.
  • Put credentials in .env and resolve them inside config/unified-push.php only — never call env() from your own code, or config:cache will silently return null. Keep .pem/.p12 files outside the web root (e.g. storage/app/push/) and confirm the PHP process can read them.
  • First use case: send a single test push from php artisan tinker to one real device token, one platform at a time. For APNS, confirm you are pointed at the sandbox gateway and using a sandbox provisioning profile; most first-run failures are environment/token mismatches, not package bugs. Once a single send succeeds, immediately wrap it in a queued job — do not call the package from a controller.

Implementation Patterns

  • Own the token lifecycle in your schema. A push_tokens table with user_id, platform (ios/android/windows), app/tenant, token, last_seen_at, and a unique index on (platform, token) prevents the duplicate sends and cross-environment token reuse that plague these integrations. Accept token registration from the client via an authenticated endpoint and upsert, don't insert.
  • Wrap the package behind your own contract. Define PushSender with send(DeviceToken $token, PushMessage $message): PushResult, implement it with this package, and bind it in a service provider. This gives you one place to normalize per-platform payloads, one place to log, and a clean migration path when the underlying protocols need replacing.
  • Build platform-specific payloads explicitly. APNS requires an aps envelope (alert, badge, sound, content-available); GCM distinguishes notification messages from data-only messages; MPNS uses its own XML/tile/toast format. Don't try to force one generic array through all three — have a PushMessage value object and per-driver serializers.
  • Queue everything and chunk bulk sends. Use a SendPushNotification job with $tries, backoff(), and chunk() on token collections (500–1000 per batch). Old APNS binary transports typically open a connection per send or per batch, so unbounded loops will stall workers. Set explicit connect/read timeouts on the underlying HTTP client where configurable.
  • Integrate with Laravel notifications where it fits. A custom NotificationChannel that resolves device tokens for the notifiable and delegates to your PushSender keeps push logic in app/Notifications and out of domain services. Keep the raw package calls out of Notification classes.
  • Handle invalid tokens as a first-class job. APNS feedback and GCM NotRegistered/InvalidRegistration responses (and canonical ID remapping) should mark tokens inactive or update them. Schedule a pruning command and a feedback-poll command, and never delete on a single ambiguous error — only on explicit unrecoverable responses.
  • Multi-app/multi-tenant credentials. If the package binds a singleton client, configure credentials per send or resolve a fresh driver instance per tenant. Cache the resolved sender per app key, and test that switching apps in one request doesn't leak the previous certificate.

Gotchas and Tips

  • The protocols are largely retired. This package predates APNS HTTP/2 + JWT provider auth (binary provider API decommissioned), the GCM→FCM migration (GCM endpoints shut down), and MPNS→WNS. It is suitable for legacy/self-hosted contexts or as a reference implementation, not as the foundation of a new production push stack. Keep it behind the PushSender contract so swapping to APNS HTTP/2 and FCM HTTP v1 is a one-class change.
  • Compatibility risk is high. Expect PHP 8 issues (reserved words, curly-brace offsets, each(), missing return types) and Laravel container/contract changes. Pin the exact version, run the test suite or a smoke script on your target PHP, and check whether the package's dependencies are themselves abandoned. MIT licensing means forking and patching is viable if you must keep it.
  • Silent failures are common. Unified-push wrappers often return booleans or arrays rather than throwing. Log the raw transport response and per-token result; treat "sent" as "accepted by the gateway," not delivered. Add metrics for accepted/failed/invalid counts per platform.
  • Environment mismatches dominate support load. APNS sandbox vs production (BadDeviceToken, Unregistered), expired certificates, wrong bundle ID/team ID, and GCM keys scoped to the wrong project all look like code failures. Build a push:diagnose {token} artisan command that prints the resolved driver, endpoint, and credential fingerprint.
  • Payload limits and encoding. APNS allows ~4 KB, GCM ~4 KB; truncation produces cryptic rejections. Use json_encode(..., JSON_UNESCAPED_UNICODE) and guard against malformed UTF-8 from user-generated content. For APNS, content-available: 1 silent pushes are throttled and must not include an alert.
  • Config and filesystem quirks. After config:cache, relative certificate paths resolve differently depending on the working directory. Always use storage_path()/base_path() in the config file. Check file permissions when running under www-data or in containers, and mount certificates as secrets rather than baking them into images.
  • Extension points are limited; plan accordingly. If the manager exposes an extend()/driver-registration hook, use it to add FCM or a mock driver for tests. If not, wrap at your PushSender boundary and inject a fake in unit tests — do not hit real gateways in CI. Keep one integration test per platform against sandbox credentials, gated by an environment flag.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle