
September 12, 2026
13 min read
By Kokil Thapa | Last reviewed: September 2026
Users ignore email. They still tap push notifications for mobile apps when the message is timely and relevant. That makes push one of the highest-leverage retention channels for booking apps, eCommerce carts, and client portals. The hard part is not the banner itself. It is token lifecycle, platform differences, and a backend that can send millions of messages without duplicating orders or leaking PII. If you already ship REST APIs for mobile clients, push belongs in the same architecture conversation as auth, webhooks, and queue workers.
How do push notifications for mobile apps work?
Push is an indirect delivery path. Your server never opens a socket to the phone. It talks to Apple or Google. Those platforms maintain persistent connections to devices and wake the app when a payload arrives.
The flow has four actors: your app, your API, the push gateway, and the device OS. Each step has a contract you must honour in production.
Registration and permission
On first launch, the app asks the OS for notification permission. iOS requires an explicit opt-in. Android 13+ also prompts at runtime. If the user declines, you cannot recover silently. You need an in-app fallback such as email or SMS.
After permission, the SDK returns a device token (FCM registration token or APNs device token). The app POSTs that token to your backend alongside user ID, platform, app version, and locale.
Delivery and display
When a business event occurs—payment confirmed, trek departure reminder, legal document uploaded—your backend enqueues a job. The worker builds a JSON payload and calls the gateway API. The OS renders the notification even when the app is killed.
Payloads split into notification fields (title, body, sound) and data fields (order ID, deep link route). Keep data minimal. Large payloads fail on some networks in Nepal where mobile data is still metered.
What is the difference between FCM, APNs, and web push?
Android and iOS use different gateways. You cannot send one HTTP request and reach both platforms unless you use a cross-platform provider or abstract the difference in your own service layer.
Firebase Cloud Messaging (FCM) handles Android and can also relay to APNs when configured. Apple Push Notification service (APNs) is mandatory for native iOS. Web push uses the W3C Push API with a service worker—useful when you are not ready for native apps. See the progressive web apps guide for that path.
| Channel | Gateway | Token type | Best for | Gotcha |
|---|---|---|---|---|
| Android native | FCM | Registration token | Play Store apps | Tokens rotate; stale tokens return 404 |
| iOS native | APNs | Device token | App Store apps | Requires .p8 key or cert; sandbox vs production |
| Cross-platform | FCM + APNs config | Platform-specific | React Native, Flutter teams | Still two credential sets behind one SDK |
| Web / PWA | Browser push service | Push subscription JSON | Budget-first rollout | iOS Safari limits until installed to home screen |
| Backend-only | OneSignal, Pusher Beams | Vendor token | Small teams without DevOps | Vendor lock-in and per-MAU pricing |
For most client projects I work on, the mobile team owns SDK integration. I own the API contract, token storage, and queued delivery. That split keeps responsibilities clear and avoids controllers calling FCM synchronously during checkout.
How should you store and manage device tokens on the backend?
Token management is where push systems quietly fail. Users reinstall apps. OS updates rotate tokens. People log in on two phones. Treat tokens as ephemeral credentials, not permanent user attributes.
Recommended schema
Store one row per token, not one token column on the users table. A typical Laravel migration looks like this:
Schema::create('device_tokens', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
$table->string('token', 512)->unique();
$table->enum('platform', ['ios', 'android', 'web']);
$table->string('app_version', 20)->nullable();
$table->string('locale', 10)->default('en');
$table->timestamp('last_used_at')->nullable();
$table->timestamps();
$table->index(['user_id', 'platform']);
}); Upsert on registration: same token updates last_used_at. Logout deletes the row for that device. Never broadcast to every token without checking user notification preferences.
Invalidation rules
When FCM returns UNREGISTERED or APNs returns status 410, delete the token immediately. Retry logic should not hammer dead endpoints. I batch invalidations in the same job that sent the push.
For high-volume apps, cache active token counts in Redis only if you have measured a read bottleneck. Most booking and eCommerce apps are fine with indexed MySQL queries on user_id.
- App opens → POST
/api/v1/device-tokenswith bearer token. - Backend upserts row and returns 204.
- Business event fires → job loads tokens for affected users.
- Worker sends per platform, logs success/failure.
- Dead tokens are deleted; transient errors retry with backoff.
Validate payloads with a JSON formatter during development. Production logs should never print full tokens—they are bearer-like secrets.
How do you implement push notifications in Laravel?
Laravel ships a notification system that supports multiple channels. Email and database notifications are common. Push fits the same pattern if you add a custom channel or use a community driver. The related Laravel notifications beyond email article covers channel architecture in depth.
On PHP 8.3+ with Laravel 12 or 13, this is the pattern I use on production apps:
Install a push driver
For FCM HTTP v1, packages such as kreait/laravel-firebase wrap authentication and message building. Configure the service account JSON in .env, never in git.
FIREBASE_CREDENTIALS=/var/www/shared/firebase-service-account.json
FCM_PROJECT_ID=your-project-id Create a notification class
<?php
namespace App\Notifications;
use Illuminate\Notifications\Notification;
use NotificationChannels\Fcm\FcmChannel;
use NotificationChannels\Fcm\FcmMessage;
class OrderShipped extends Notification
{
public function __construct(private int $orderId) {}
public function via(object $notifiable): array
{
return [FcmChannel::class, 'database'];
}
public function toFcm(object $notifiable): FcmMessage
{
return FcmMessage::create()
->title('Your order is on the way')
->body('Track delivery in the app.')
->data(['order_id' => (string) $this->orderId]);
}
} Dispatch through a queue
Always queue notification sending. A payment webhook should not wait on Google’s API latency.
$user->notify(new OrderShipped($order->id)); Ensure ShouldQueue is implemented on the notification or run the notifiable through a queued listener. Pair this with Horizon or database queue workers on Ubuntu 22/24—the same stack I use for Linux production hosting.
For WooCommerce-backed mobile storefronts, order events often originate in WordPress. A webhook into Laravel—or direct integration via the WooCommerce REST API—should trigger the same notification classes. One source of truth for message copy avoids the app saying "shipped" while email says "processing".
What security and privacy rules apply to push payloads?
Push travels through third-party infrastructure. Assume Google and Apple can read notification title and body fields. Never put passwords, full card numbers, or unredacted legal documents in the alert text.
Put sensitive detail behind an authenticated in-app fetch. The notification says "New message" and the app loads content after login. This aligns with mobile app security basics and Nepal’s data-handling expectations for client portals.
- Sign APNs requests with a rotated .p8 key stored outside the web root.
- Restrict Firebase service accounts to Cloud Messaging only.
- Rate-limit the token registration endpoint to prevent token flooding attacks.
- Respect user opt-out flags before every send—not only at registration.
- Log delivery metadata, not message body content, in production.
Deep links must validate the target resource belongs to the logged-in user. A guessable order ID in a data payload is an IDOR waiting to happen.
What are common push notification mistakes in production?
Most failures I debug are operational, not SDK bugs. Teams treat push as a frontend feature and skip backend discipline.
Sending from the request cycle
A controller that calls FCM inline during checkout adds 200–800 ms latency. Worse, a timeout can mark payment ambiguous while the user already received a push. Queue everything.
Ignoring timezone and locale
A booking reminder at 02:00 local time gets notifications disabled. Store user timezone on the profile. Schedule reminders with Laravel’s task scheduler and respect quiet hours. For Nepali apps, BS date display belongs in the app UI—not in the push channel logic.
Over-notification
Marketing teams want daily blasts. Product teams want retention. Users uninstall. Cap promotional pushes per week. Transactional messages—OTP, receipt, booking change—get priority.
Skipping staging credentials
APNs sandbox tokens fail against production endpoints. I have seen week-long debug sessions caused by one wrong boolean. Document which build flavour maps to which APNs environment. Automate checks in mobile CI/CD with Fastlane if your team uses it.
No fallback channel
Push is best-effort. SMS or email should confirm critical actions—payment received, court appointment booked, trek permit issued. On a trekking booking platform like Adventure Third Pole Trek, departure changes need guaranteed delivery through at least two channels.
How do web push and native push fit together?
Not every business needs an App Store release on day one. Web push via a service worker covers Android desktop and many Android phones. iOS web push improved but still expects a installed PWA for reliable delivery.
A sensible 2026 rollout for a Nepal SMB:
- Launch responsive web app with optional web push.
- Measure repeat usage and notification opt-in rate.
- Ship native app when offline features or store presence justify the cost—often Rs 800,000–2,000,000 (~USD 6,000–15,000) for a focused v1.
- Reuse the same Laravel notification classes; swap the channel driver per platform.
MDN’s Push API documentation is the authoritative reference for VAPID keys and subscription objects. Keep web and native tokens in the same table with a platform discriminator.
For eCommerce, tie push to cart and order events the same way you would wire Khalti or eSewa callbacks—idempotent, logged, and testable. See eCommerce development for full checkout architecture.
How do you test and monitor push delivery?
Testing starts in sandbox. Use Firebase console for manual Android sends. Use APNs sandbox with development provisioning profiles on real devices—simulators do not fully replace device behaviour for remote notifications.
Automated tests should mock the HTTP client. Assert the notification class builds the correct payload. One integration test against sandbox per deploy is enough for most teams.
Monitor these metrics:
- Send success rate by platform
- Token invalidation rate (spike means app bug or cert rotation)
- Queue latency for notification jobs
- Tap-through rate per notification type
- Opt-out rate after promotional campaigns
Pair push monitoring with broader testing and optimization practices. OpenTelemetry traces from the related instrumentation guide help correlate slow checkout with failed notification jobs.
On the marketing side, poor mobile engagement hurts mobile-first indexing signals indirectly when users bounce back to search. Push is retention, not SEO—but retained users generate the behavioural data that supports organic growth.
Key Takeaways
- Push notifications for mobile apps flow through FCM and APNs—your backend stores tokens and queues delivery, never calling gateways inline from controllers.
- Use a dedicated
device_tokenstable, delete stale tokens on 404/410 responses, and never store tokens in JWTs or session cookies. - Keep notification title/body free of PII; load sensitive content after the user opens the app and authenticates.
- Separate transactional and promotional sends with opt-in checks, quiet hours, and weekly caps.
- Laravel notification channels plus queue workers give you the same architecture for native push, web push, email, and SMS.
- Always maintain a fallback channel for critical business events—push alone is not guaranteed delivery.
People Also Ask
Do push notifications work when the app is closed?
Yes. That is the primary value of push notifications for mobile apps. The OS receives the payload from FCM or APNs and renders the alert independently of app process state. Data-only messages may require background handler support on Android.
How much do push notifications cost?
FCM and APNs delivery is free at platform level. Costs come from backend compute, queue infrastructure, and optional third-party providers. Expect Rs 0 direct per message unless you use a paid aggregator with per-MAU pricing above free tiers.
Can Laravel send push notifications without a mobile app?
Yes. Laravel can send web push through service worker subscriptions using the same notification system. Native Android and iOS require respective SDKs in those apps, but the server-side pattern stays identical.
Why do push notifications stop working after an app update?
Common causes include expired APNs certificates, wrong sandbox/production endpoint, changed Firebase google-services.json, or tokens not re-registered on first launch after update. Check gateway error responses before blaming the mobile codebase.
Ship push the right way from your backend
Push notifications for mobile apps succeed when backend engineers treat them like payments: idempotent jobs, clear contracts, token hygiene, and fallbacks when delivery fails. Native SDK work belongs to your mobile team or agency partner. The API, queue layer, and notification rules belong in the same Laravel or Symfony codebase that already powers your custom software and enterprise workflows.
If you are planning a booking app, eCommerce companion, or client portal with real-time alerts, map your event list before you write SDK code. I help teams design that layer—token APIs, queued delivery, and integration with existing mobile architecture—so notifications ship reliably in production. Contact us to discuss your project, or browse the portfolio for apps that already depend on timely user alerts.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

