Skip to main content

Push Notifications Quick Start Guide

Overview

This guide provides a quick reference for implementing and working with ZÈYA's push notification system.

📋 Documentation Index

Main Documentation Files

  1. Push Notifications Architecture

    • System overview and architecture diagrams
    • Complete data flow documentation
    • Integration points and components
  2. API Push Notifications

    • Backend implementation details
    • Database schema and models
    • API endpoints and services
    • Queue jobs and bulk sending
    • Performance optimization
  3. Mobile App Push Notifications

    • Mobile app implementation
    • Permission handling
    • Token registration
    • Notification listeners
    • Deep linking

🚀 Quick Implementation

Backend (API)

1. Send a notification to a user:

use App\Http\Controllers\NotificationController;

$message = [
'title' => 'You got a match!',
'body' => 'Someone wants to swap with you',
'data' => [
'link' => '/swap/123',
'transaction_id' => 123
]
];

NotificationController::sendNotification($message, [user_id]);

2. Send bulk notifications:

use App\Jobs\SendBulkNotifications;

$message = [
'title' => 'New Feature!',
'body' => 'Check out our latest update',
'data' => ['link' => '/features']
];

SendBulkNotifications::dispatch($message);

Mobile App

1. Setup notifications in your component:

import { usePushNotifications } from '../../share/useNotifications';

function MyComponent() {
const { expoPushToken, notification, response } = usePushNotifications();

// Token is automatically registered with backend
// Notifications are automatically handled

return <YourUI />;
}

2. Listen to notification events:

import { on, off } from './emitter';

useEffect(() => {
const handleNotification = (notification) => {
// Handle notification received
console.log('New notification:', notification);
};

on('notification.received', handleNotification);

return () => off('notification.received', handleNotification);
}, []);

📊 API Endpoints

User Endpoints

# Save device token
POST /api/user/save-phone-token
Authorization: Bearer {token}
{
"token": "ExponentPushToken[xxx]",
"device_id": "uuid",
"platform": "ios"
}

# Get notifications
GET /api/notification
Authorization: Bearer {token}

# Mark as read
GET /api/notification/{id}/read
Authorization: Bearer {token}

Admin Endpoints

# Send test notification
GET /api/send-test-notification?user_id=123&title=Test&text=Hello
Authorization: Bearer {token}

# Send to all users
POST /api/admin/send-notification-all
Authorization: Bearer {admin-token}
{
"title": "Announcement",
"text": "Message body",
"data": {"link": "/page"}
}

# Get promotional notifications
GET /api/admin/promotional-notifications?page=1&per_page=10
Authorization: Bearer {admin-token}

# Process delivery receipts
GET /api/admin/process-receipts?limit=200
Authorization: Bearer {admin-token}

🔧 Configuration

Backend Environment Variables

# Expo Push Notifications
EXPO_ACCESS_TOKEN=your_expo_token

# Firebase (for badge sync)
FIREBASE_CREDENTIALS=path/to/credentials.json
FIREBASE_DATABASE_URL=https://your-project.firebaseio.com

# Queue Configuration
QUEUE_CONNECTION=redis
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379

Mobile App Configuration

// app.json
{
"expo": {
"extra": {
"eas": {
"projectId": "your-expo-project-id"
}
}
}
}

📈 Monitoring

Check Delivery Status

-- Overall stats
SELECT
COUNT(*) as total,
SUM(is_send) as sent,
SUM(is_delivered) as delivered,
SUM(is_open) as opened
FROM notifications
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY);

-- Failed notifications
SELECT error_message, COUNT(*) as count
FROM notifications
WHERE is_send = false
AND error_message IS NOT NULL
GROUP BY error_message
ORDER BY count DESC;

Queue Monitoring

# Check queue status
php artisan queue:work --queue=default --sleep=3 --tries=3

# Monitor failed jobs
php artisan queue:failed

🐛 Common Issues

1. Notifications Not Sending

Check:

  • Queue is running: php artisan queue:work
  • User has valid device token in database
  • User notification preference is enabled

Fix:

# Restart queue workers
php artisan queue:restart

# Check for failed jobs
php artisan queue:failed

2. DeviceNotRegistered Error

Cause: Token is invalid or expired

Fix:

// Remove invalid token
MobileDevice::where('token', $invalidToken)->delete();

// User needs to restart app to register new token

3. Mobile App Not Receiving

Check:

  • Device has notification permission granted
  • App is connected to internet
  • Expo push token is registered with backend
  • Check notification channel settings (Android)

Debug:

// Check token
const token = await Notifications.getExpoPushTokenAsync();
console.log('Token:', token);

// Check permission
const { status } = await Notifications.getPermissionsAsync();
console.log('Permission:', status);

📝 Best Practices

Backend

  1. Always batch notifications

    // Good ✅
    NotificationController::sendNotification($msg, [1,2,3,4,5]);

    // Bad ❌
    foreach ($users as $user) {
    NotificationController::sendNotification($msg, [$user]);
    }
  2. Use queues for bulk sends

    // Good ✅
    SendBulkNotifications::dispatch($message);

    // Bad ❌
    foreach ($users as $user) {
    NotificationService::send($message, [$user]);
    }
  3. Keep payload small

    • Max 4KB per notification
    • Use IDs, not full objects
    • Store large data in DB

Mobile App

  1. Request permission at right time

    // Good ✅ - When user enables feature
    function handleEnableNotifications() {
    Notifications.requestPermissionsAsync();
    }

    // Bad ❌ - On app launch
    useEffect(() => {
    Notifications.requestPermissionsAsync();
    }, []);
  2. Clean up listeners

    useEffect(() => {
    const listener = Notifications.addNotificationReceivedListener(...);
    return () => listener.remove(); // ✅ Always cleanup
    }, []);
  3. Update token on launch

    useEffect(() => {
    registerForPushNotificationsAsync().then((token) => {
    // Always re-register on app launch
    updateTokenOnBackend(token);
    });
    }, []);

Internal Documentation

External Resources

📞 Support

For issues or questions:

  1. Check the detailed documentation above
  2. Search for error messages in logs
  3. Test with Expo Push Tool
  4. Contact the development team

🔄 Quick Command Reference

Backend

# Start queue worker
php artisan queue:work

# Check failed jobs
php artisan queue:failed

# Retry failed jobs
php artisan queue:retry all

# Clear queue
php artisan queue:clear

Mobile App

# Start development
npm start

# Run on iOS
npm run ios

# Run on Android
npm run android

# Build for production
eas build --platform ios
eas build --platform android

Database

# Run migrations
php artisan migrate

# Check notification counts
php artisan tinker
>>> Notification::count()
>>> Notification::where('is_send', true)->count()

Last Updated: January 2026

For comprehensive details, see the full documentation.