redjanym/fcm-bundle
A Symfony bundle for Firebase Cloud Messaging (FCM) that provides simple services and configuration to send push notifications to Android and iOS devices through Google's FCM HTTP API.
Architecture fit
Bundle class registration, DI extension config trees, and services.yaml conventions. Laravel has no equivalent loading mechanism, so the bundle cannot be installed and used as-is in a Laravel application. v2.1.1 does not change this — a PHP-version support statement modifies a composer constraint, not the loading model.Integration feasibility
NotificationChannel, and a queued job. This is a small, well-bounded piece of glue — roughly one to two developer-days plus test coverage.google/auth for OAuth2. Viable, but re-implements token refresh, retry, and message-shape logic that this package already encodes.Technical risk
google/auth and Guzzle/PSR versions. Version pins may lag PHP minor releases. The v2.1.1 change may itself have loosened the PHP constraint — which cuts both ways: easier install, weaker guarantee that the maintainer has tested on our runtime.Key questions
composer.json diff between the previous tag and v2.1.1, not the release notes.UNREGISTERED, SENDER_ID_MISMATCH) in a way we can feed a token-pruning job?Stack fit
| Concern | Fit | Note |
|---|---|---|
| Laravel service container | Poor (as bundle) / Good (as library) | Requires a hand-written service provider and config entry |
| Queue workers / Horizon | Good | Send belongs on a queue; retries map cleanly to job retries |
| Secret management | Neutral | Service-account JSON must live in our secrets store, not .env in plaintext |
| Observability | Weak | Expect to add our own logging/metrics around the client |
| PHP 8.2+ / Laravel 10–12 | Likely good, now marginally better signalled | v2.1.1 asserts PHP 8+; still verify the actual composer constraint diff and Laravel 12 dependency resolution |
Migration path
PushChannel interface with an FCM v1 implementation backed by the client library; device-token repository; invalid-token pruning consumer.Compatibility
symfony/* pins and Guzzle major. Run composer why-not / a throwaway composer require in a scratch Laravel skeleton before scheduling work.Sequencing
composer.json diff.Maintenance
Support
Scaling
Failure modes
| Mode | Symptom | Mitigation |
|---|---|---|
| Invalid/expired device token | UNREGISTERED / NOT_REGISTERED |
Consume error codes, prune tokens in a background job |
| Access-token expiry or clock skew | 401 from FCM | Refresh proactively; ensure NTP-synced hosts |
| Service-account key revoked/rotated | Total send failure | Rotation runbook, alerting on 401 rate, dual-key overlap window |
| Quota exhaustion / 429 | Retry storm | Exponential backoff with jitter; per-type rate limits |
| Oversized payload (>4 KB) | 400 rejection | Validate payload size at enqueue time |
| Data-only message not delivered | Silent no-op in background | Use notification + data for user-visible sends |
| APNs-specific rejection | Android fine, iOS silent | Per-platform config and separate error surfacing |
| Silent drop, no error | Delivery rate quietly falls | Track send-to-delivery ratio as a first-class metric |
| Untested PHP patch upgrade | Fatal error at boot after a routine bump | Pin exact versions; stage dependency bumps through CI, never auto-merge |
Ramp-up
Recommendation Adopt the capability, not the package. Vendor the underlying FCM v1 client behind a Laravel-native adapter, pin aggressively, pre-approve a fork, and treat the bundle itself as reference implementation. v2.1.1 is a compatibility note, not a change in posture: it modestly improves the PHP-runtime story and confirms the maintainer is still active, but it arrives as a patch release with a one-line changelog that leaves Symfony/Guzzle constraints and tested PHP minors undeclared. The package still scores well against a generic quality model, but its ecosystem signal (43 stars, 0 dependents, single maintainer) means the score should not be read as production-readiness — the decision rests on Google's API stability, which is strong, and our willingness to own a small amount of glue, which is modest.
How can I help you explore Laravel packages today?