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

Rms Push Notifications Bundle Laravel Package

msouverain/rms-push-notifications-bundle

A Symfony bundle that brings push notification delivery into your application's service container, offering a reusable way to dispatch messages to mobile clients from your backend instead of wiring notification logic into every project.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: msouverain/rms-push-notifications-bundle is a Symfony bundle, not a Laravel package. It has 0 stars, 0 dependents, and no observable maintenance. The name and structure indicate it is a fork/descendant of the classic Symfony2 RMS\PushNotificationsBundle, which wrapped the (now-retired) Apple binary provider API and Google GCM. Treat this as source material to port, not as a composer require dependency.

Minimal steps:

  1. Inspect before installing. Open composer.json and check the require block. Expect symfony/framework-bundle, symfony/config, symfony/dependency-injection with ~2.x/~3.x constraints. If so, Composer will not resolve it inside a Laravel 10/11 app (Laravel already pins symfony/* to 6/7).
  2. Vendor the code instead of requiring it. Clone the repo and copy src/ into app/Support/Push/ (or a packages/ path repository with "type": "path"), then fix the autoload namespace to PSR-4 in your own composer.json. The message/payload classes are usually plain PHP and survive the transplant; the DI extension and services.xml do not.
  3. Look at, in order: src/Message/ (payload objects), src/Service/ (the senders), DependencyInjection/Configuration.php (what config keys exist: certificates, API keys, sandbox flags), and Resources/config/services.xml (the service ids you'd otherwise autowire).
  4. First use case — deliberately narrow: build one iOSMessage/AndroidMessage, set the device token and a payload array, and dump the serialized payload. That is the only part of this package with durable value. Do not start by wiring the actual socket/HTTP send path; see Gotchas.
// Goal of step 4: confirm you can construct a payload without the Symfony container
$message = new \RMS\PushNotificationsBundle\Message\iOSMessage();
$message->setDeviceIdentifier($token);
$message->setMessage('Hello');
$message->setData(['order_id' => 42]);
dump($message->getPayload()); // inspect shape; this is what you keep

Implementation Patterns

1. Bind the library behind your own contract. The single most important pattern: never let RMS\... classes leak into controllers or jobs. Define an interface and adapt.

// app/Contracts/PushTransport.php
interface PushTransport
{
    public function send(PushMessage $message): PushResult;
}

// app/Services/Push/LegacyRmsAdapter.php — wraps the vendored classes
class LegacyRmsAdapter implements PushTransport
{
    public function send(PushMessage $message): PushResult
    {
        $rms = $message->platform() === 'ios'
            ? new iOSMessage()
            : new AndroidMessage();

        $rms->setDeviceIdentifier($message->token());
        $rms->setMessage($message->body());
        $rms->setData($message->data());

        return $this->senderFor($message->platform())->send($rms);
    }
}

2. Port the bundle config into config/push.php. The Symfony tree (rms_push_notifications.ios.certificate, .sandbox, .android.api_key) maps cleanly onto a Laravel config file plus .env entries. Do the mapping once in a service provider rather than scattering env() calls in adapters.

// config/push.php
return [
    'ios' => [
        'certificate' => env('PUSH_IOS_CERT'),
        'passphrase'  => env('PUSH_IOS_PASSPHRASE'),
        'sandbox'     => env('PUSH_IOS_SANDBOX', false),
    ],
    'android' => ['api_key' => env('PUSH_ANDROID_KEY')],
];

3. Queue and fan out. Push is I/O-bound and flaky; always go through a job. One job per device token (not per message) gives you independent retries and clean failure accounting.

class SendPushNotification implements ShouldQueue
{
    use Queueable, InteractsWithQueue;

    public int $tries = 3;
    public array $backoff = [10, 60, 300];

    public function __construct(
        public int $deviceId,
        public string $body,
        public array $data = [],
    ) {}

    public function handle(PushTransport $transport): void
    {
        $device = DeviceToken::find($this->deviceId);
        if (! $device || $device->is_stale) {
            return; // idempotent no-op
        }

        $transport->send(new PushMessage(
            platform: $device->platform,
            token: $device->token,
            body: $this->body,
            data: $this->data,
        ));
    }
}

4. Persist tokens with a real model. The bundle has no storage layer at all — it just takes an identifier string. You own device_tokens (user_id, platform, token unique, last_seen_at, is_stale) and the registration endpoint. Uniqueness should be on token, not (user_id, token): a token can migrate between users on a shared device.

5. Treat "feedback" as your own pruning loop. Older APNS bundles shipped a feedback-service reader; that endpoint is gone. Replace it with your own rule: mark is_stale on a permanent failure (unregistered/bad token) returned by the transport, and prune on a schedule. This keeps the adapter's error semantics meaningful.

6. Swap-friendly tests. Because everything goes through PushTransport, tests bind a RecordingPushTransport and assert on PushMessage value objects. You never need to boot the vendored senders in CI, which is good — they open raw sockets.

Gotchas and Tips

  • The transports are dead, and this is the headline issue. The package targets the legacy APNS binary gateway (gateway.push.apple.com:2195, retired by Apple in 2021) and GCM (shut down in 2019, superseded by FCM). The message-building and token-management patterns still apply, but the send path will not deliver to modern devices. Plan to replace the socket/HTTP layer with APNs HTTP/2 + JWT (or kreait/firebase-php for FCM) and keep only the payload construction.
  • Symfony bundle ≠ Laravel package. There is no service provider, no extra.laravel auto-discovery, no facade. DependencyInjection/RMSPushNotificationsExtension.php only runs under Symfony's kernel. If you copy code in, delete the DI wiring rather than trying to emulate it — a single bind() in AppServiceProvider is the whole story.
  • Dependency resolution will bite. If composer.json pins Symfony 2/3 components, do not force it with --ignore-platform-reqs. That produces two incompatible copies of symfony/config in vendor/ and failures that look unrelated. Vendor the classes.
  • PSR-0 vs PSR-4. This vintage of bundle may use PSR-0 directory layouts (RMS/PushNotificationsBundle/...). Rename/move to PSR-4, or your autoloader will silently miss classes and you'll get "class not found" only at runtime.
  • Certificate handling on iOS. .pem (cert+key concatenated) vs .p12 trips people up; also sandbox vs production host mismatch produces a generic disconnect, not a clear error. Verify the certificate's environment and expiry with openssl x509 -in cert.pem -noout -dates before debugging code.
  • Payload size limits. APNs and FCM both cap around 4 KB; oversized payloads are rejected wholesale, not truncated. Log the serialized byte length in the job before sending — this catches 90% of "works in dev, silently fails in prod" reports.
  • No maintenance = supply-chain risk. With 0 stars and 0 dependents there's no community review. Audit every socket/HTTP call and any exec/file_get_contents usage before it enters your codebase, and pin the exact commit you vendored so the diff is reviewable later.
  • Best extension point is the sender, not the message. Message classes are value objects — extend them freely. The senders are where the dead protocol lives; wrap them behind your own interface (pattern 1) so the day you migrate to HTTP/2 you change one class and delete the rest.
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.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console