July 30, 2026 — The unofficial Laracon US Day 3. Get your ticket to The Vibes
Plugin Marketplace

nativephp/mobile-firebase

Firebase plugin for NativePHP Mobile (Push notifications via FCM/APNs)

Push Notifications Plugin for NativePHP Mobile#

Push notifications via Firebase Cloud Messaging (FCM) for NativePHP Mobile apps. Handles device registration, token management, permission flow, deep linking from notifications, data-only messages with background processing, and server-side sending.

Works on iOS (APNs via FCM) and Android (FCM).


Installation#

Copied!
composer require nativephp/mobile-firebase

Firebase Setup#

Android#

  1. Create a Firebase project at Firebase Console
  2. Add your Android app (use your app's package name)
  3. Download google-services.json and place it in your project root
  4. The plugin compiler copies it to the Android build automatically

iOS#

  1. In the same Firebase project, add your iOS app
  2. Download GoogleService-Info.plist and place it in your project root
  3. Enable Push Notifications capability in your Apple Developer account
  4. Upload your APNs key to Firebase Console > Project Settings > Cloud Messaging
  5. The plugin compiler handles Xcode configuration automatically

Server-Side#

To send push notifications from your server, you need a Firebase service account:

  1. Firebase Console > Project Settings > Service Accounts
  2. Click "Generate new private key"
  3. Save the JSON file and set the path in your .env:
Copied!
FIREBASE_CREDENTIALS=/path/to/service-account.json

Quick Start#

Copied!
use Native\Mobile\Facades\PushNotifications;
 
// 1. Check current permission status
$status = PushNotifications::checkPermission();
 
// 2. Enroll for push notifications (prompts user if needed)
PushNotifications::enroll();
 
// 3. Handle the token when it arrives
Copied!
use Native\Mobile\Attributes\OnNative;
use Native\Mobile\Events\PushNotification\TokenGenerated;
 
#[OnNative(TokenGenerated::class)]
public function handleToken(string $token)
{
// Send token to your server and store it for this user
$this->user->update(['push_token' => $token]);
}

Permission Flow#

Checking Permission#

Always check before prompting. This does not trigger a system dialog.

Copied!
$status = PushNotifications::checkPermission();
// Returns: "granted", "denied", "not_determined", "provisional", or "ephemeral"
Status Description
granted User allowed notifications
denied User denied — direct them to system Settings
not_determined Never asked — safe to call enroll()
provisional Quiet notifications allowed (iOS only)
ephemeral App Clips only (iOS)

Enrolling#

Requests permission (if not_determined) and registers for push notifications. On success, a TokenGenerated event fires with the device token.

Copied!
PushNotifications::enroll();

If permission is already granted, calling enroll() skips the dialog and immediately fetches the token.

Getting the Token#

Retrieve the cached token at any time:

Copied!
$token = PushNotifications::getToken();

Returns the FCM token on Android, APNs/FCM token on iOS, or null if not yet enrolled.


Events#

TokenGenerated#

Fired when a push token is available after enrollment.

PHP (Livewire)

Copied!
use Native\Mobile\Attributes\OnNative;
use Native\Mobile\Events\PushNotification\TokenGenerated;
 
#[OnNative(TokenGenerated::class)]
public function handleToken(string $token)
{
// Store token on your server for this user/device
$this->user->update(['push_token' => $token]);
}

JavaScript (Vue)

Copied!
import { On, Off, Events } from '#nativephp';
import { onMounted, onUnmounted } from 'vue';
 
const handleToken = ({ token }) => {
// Send to your backend
fetch('/api/push-token', {
method: 'POST',
body: JSON.stringify({ token }),
});
};
 
onMounted(() => On(Events.PushNotification.TokenGenerated, handleToken));
onUnmounted(() => Off(Events.PushNotification.TokenGenerated, handleToken));

JavaScript (React)

Copied!
import { On, Off, Events } from '#nativephp';
import { useEffect } from 'react';
 
useEffect(() => {
const handler = On(Events.PushNotification.TokenGenerated, ({ token }) => {
sendTokenToServer(token);
});
return () => Off(Events.PushNotification.TokenGenerated, handler);
}, []);

PushNotificationReceived#

Fired when a data message arrives (background processing).

Copied!
use Native\Mobile\Attributes\OnNative;
use Native\Mobile\Events\PushNotification\PushNotificationReceived;
 
#[OnNative(PushNotificationReceived::class)]
public function handlePush($data)
{
// Process the incoming data
}

Sending Notifications#

Test Command#

Send a test notification from your terminal:

Copied!
# Basic notification
php artisan fcm:send {token} --title="Hello" --body="World"
 
# With deep link
php artisan fcm:send {token} --title="New Order" --body="Order #123 ready" --url="/orders/123"
 
# Data-only (silent, triggers background processing)
php artisan fcm:send {token} --data-only --d event=App\\Events\\SyncNeeded --d payload='{"sync_id":42}'
 
# With badge count
php artisan fcm:send {token} --title="Messages" --body="3 unread" --badge=3
 
# Custom data pairs
php artisan fcm:send {token} --title="Update" --d type=order --d order_id=55

Sending from PHP#

Use the FCM v1 API with your service account credentials:

Copied!
use Illuminate\Support\Facades\Http;
 
$response = Http::withToken($accessToken)
->post("https://fcm.googleapis.com/v1/projects/{$projectId}/messages:send", [
'message' => [
'token' => $deviceToken,
'notification' => [
'title' => 'Order Shipped',
'body' => 'Your order is on the way!',
],
'data' => [
'url' => '/orders/123',
],
],
]);

Deep Linking#

Push notifications can navigate users to specific screens when tapped. Include a url or link key in the data payload:

Copied!
{
"message": {
"token": "device-token",
"notification": {
"title": "New Message",
"body": "You have a new message"
},
"data": {
"url": "/messages/42"
}
}
}

The app navigates to the URL on tap, even from a cold start.


Data Messages (Background Processing)#

Send data-only messages to trigger server-side Laravel event processing without showing a visible notification. Include an event key in the data payload:

Copied!
{
"message": {
"token": "device-token",
"data": {
"event": "App\\Events\\DataSyncRequested",
"payload": "{\"sync_id\": 42}"
},
"apns": {
"payload": {
"aps": {
"content-available": 1
}
}
}
}
}

The plugin spins up an ephemeral PHP runtime on the device to dispatch the event, even when the app is in the background. Your Laravel event listeners run natively on the device.


JavaScript API#

Copied!
import { PushNotifications, On, Events } from '#nativephp';
 
// Check permission
const { status } = await PushNotifications.checkPermission();
 
// Enroll (prompts if not_determined)
if (status === 'not_determined') {
await PushNotifications.enroll();
}
 
// Get cached token
const { token } = await PushNotifications.getToken();
 
// Clear badge
await PushNotifications.clearBadge();
 
// Listen for token
On(Events.PushNotification.TokenGenerated, ({ token }) => {
console.log('Token:', token);
});

Don't call enroll() immediately on app launch. Show a pre-prompt first:

  1. Call checkPermission() to get current status
  2. If not_determined, show a custom UI explaining why notifications are valuable
  3. User taps "Enable" — call enroll()
  4. System dialog appears
  5. If granted, TokenGenerated fires
  6. Send token to your server
  7. If denied, show a message directing users to Settings
Copied!
public function requestPush()
{
$status = PushNotifications::checkPermission();
 
if ($status === 'denied') {
Dialog::toast('Enable notifications in Settings');
return;
}
 
PushNotifications::enroll();
}

Platform Notes#

Feature iOS Android
Permission prompt System dialog via UNUserNotificationCenter System dialog on API 33+ (auto-granted below)
Token type APNs token → FCM token (if Firebase configured) FCM token
Background data messages Ephemeral PHP runtime Ephemeral PHP runtime
Deep linking Via url or link in data payload Via url or link in data payload
Badge Set via APNs payload OS-managed badge dots
clearBadge() Resets to zero Cancels all displayed notifications
Firebase config GoogleService-Info.plist in project root google-services.json in project root

Coexistence with Local Notifications#

This plugin works alongside nativephp/mobile-local-notifications. On iOS, the local notifications plugin chains its delegate to this plugin's delegate automatically — both receive their respective callbacks without conflict.


License#

MIT License. See LICENSE for details.