laravel-notification-channels/fcm
A Laravel notification channel for Firebase Cloud Messaging (FCM). Send push notifications to Android, iOS, and web devices through Laravel's notification system, with support for topics, data payloads, and the FCM HTTP v1 API.
Architecture fit
The package remains a thin, idiomatic extension of Laravel's notification subsystem, but 6.0.0 broadens the surface from one channel to two. FcmChannel still handles unicast sends via toFcm($notifiable) and routeNotificationForFcm(), while the new FcmTopicChannel addresses sends by topic name — which shifts fan-out responsibility from your application to FCM's subscription model. Architecturally this is the right direction: topic messaging is the sanctioned answer to linear HTTP fan-out, and it means the package now covers both the transactional (per-token) and broadcast (per-topic) shapes that previously forced teams to hand-roll one of them. The new android/ios helpers on the message class are a payload-construction convenience, not a new abstraction — they reduce the chance of a malformed APNs block but do not validate rendering. It is still not a device-token registry, a topic-subscription manager, a fan-out service, or a delivery-analytics layer; those remain yours.
Integration feasibility
Still low-friction on the happy path, but the entry gate has moved. Composer install, auto-discovery, publish config, service account JSON — roughly a half-day to a first send, unchanged. What changed is who can install it: requiring PHP 8.4+ and Laravel 12+ means teams on Laravel 10 or 11 cannot adopt 6.x at all and must either upgrade the host application first or stay on the 5.x line. Treat the Laravel/PHP upgrade as a prerequisite workstream with its own estimate, not as part of the package spike. For teams already on Laravel 12 / PHP 8.4, integration effort is unchanged; add a short increment for topic design if you plan to use FcmTopicChannel.
Technical risk
kreait/firebase-php / google/auth — audit that transitive tree for advisories and for conflicts with any other Firebase integration you run.Key questions
kreait/firebase-php / google/auth majors does 6.0.0 pin, and are there breaking changes in that transitive bump beyond the framework requirement?FcmTopicChannel support conditions ('topicA' in topics && 'topicB' in topics), or single-topic sends only — and does it expose subscribe/unsubscribe, or is subscription management entirely on the application and the mobile clients?UNREGISTERED/INVALID_ARGUMENT, or return silently?android/ios helpers emit a complete, correct APNs block (headers, aps payload, interruption levels), or are they thin array shorthands that still require manual correctness?Stack fit
Clean fit for Laravel 12 / PHP 8.4 backed by a queue (Redis/SQS/database) and Horizon for visibility. No new infrastructure — outbound HTTPS to Google's endpoints plus a secrets store is still the whole story. Two stack-fit checks are now gating rather than advisory: (a) confirm the host application is actually on Laravel 12 and PHP 8.4 before planning around 6.x; (b) re-run the dependency audit if kreait/laravel-firebase or any other Firebase consumer is present, because 6.0.0 moves the shared kreait/firebase-php pin. If the app is on Laravel 10/11, this assessment assumes you either schedule the framework upgrade or explicitly accept 5.x as a frozen dependency with a fork plan.
Migration path
Two migrations, sequenced — do not conflate them. First the package upgrade (5.x → 6.x, gated on the framework/PHP bump), then the feature adoption (topic channel, platform helpers). Recommended path:
android/ios helpers are additive, but confirm no default payload shape changed in the major.FcmTopicChannel behind a feature flag, with clients subscribing to topics on login and unsubscribing on logout/token rotation.Compatibility
Pin the package major explicitly and lock the transitive kreait/firebase-php / google/auth versions in a dependency-audit step — the 6.0.0 bump changes both the framework floor and that tree. Run composer why-not against the target Laravel version in CI. Record a deliberate decision on the 5.x branch: either "we upgrade within N months" or "we pin 5.x and accept that it is frozen," with the second option carrying a documented fork owner. Note the historical pattern — this package has now demonstrated it will move to a new Laravel major on its own schedule, and it will likely do so again for Laravel 13; assume a repeat of this exact upgrade exercise on that horizon and budget for it.
Sequencing
Framework/PHP upgrade first (blocking, and newly blocking), then credential and secret management (still blocking), then a staging spike proving HTTP v1 auth works on 6.x, then token-storage schema and cleanup job, then unicast channel integration per notification type, then topic integration and subscription lifecycle for broadcast paths, then observability. Do not sequence observability last — per-message FCM error codes remain the only way to detect the silent-failure class below, and they are now needed on two channels.
Maintenance
Low ongoing code cost, but the vigilance cost has shifted in character. The dominant maintenance event is no longer "Google changes the FCM API" — it is "the package moves to a new Laravel major and drops the one you are on." That is now a known, repeatable pattern with a known cost: a framework upgrade plus a package major plus a re-test of every notification type. Put that on a recurring roadmap slot rather than treating it as a surprise. Assign a named internal owner and a documented fork-and-patch procedure that covers both the FCM-API-change scenario and the abandoned-5.x-branch scenario.
Support
Community GitHub issues only, unchanged. Treat the package as internal code you happen to import. The wrapper recommendation is now more valuable, not less: put FcmChannel and FcmTopicChannel behind your own thin notifier service so that a swap to a direct HTTP v1 client — or a fork — is a one-file change. If you operate both a transactional and a broadcast path, keep them behind the same wrapper so a fork costs you one patch rather than two.
Scaling
Materially improved by this release. Broadcast traffic that previously fanned out linearly in HTTP calls can now go through FcmTopicChannel, which removes the per-token call volume that dominated large-audience sends. Practical consequences:
Failure modes
UNREGISTERED/INVALID_ARGUMENT and without a pruning job error rates and cost grow monotonically.android/ios helpers, which reduce hand-built APNs mistakes — but they do not validate rendering. Messages that render on Android still drop on iOS if the apns block is incomplete, and data-only messages still fail silently when the app is force-quit. Device-matrix testing remains required.Ramp-up
A Laravel-fluent engineer on Laravel 12 reaches a working unicast send in under a day, and a working topic send in a second day. Production readiness — token hygiene, topic subscription lifecycle, error-code observability across two channels, queue isolation, secret rotation, and a documented fork/fallback — is realistically 4–6 engineer-days including review and staging validation. The upper end assumes you are standing up topic subscription management for the first time. The package is still not the cost; the operational envelope around it is, and 6.0.0 adds one new line item to that envelope (subscription lifecycle) while removing a larger one (per-token fan-out at scale). Add the framework/PHP upgrade separately if you are not already there — that is the dominant cost in this release, and it is not the package's fault, but it is the package's price of admission.
How can I help you explore Laravel packages today?