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
-
Push Notifications Architecture
- System overview and architecture diagrams
- Complete data flow documentation
- Integration points and components
-
- Backend implementation details
- Database schema and models
- API endpoints and services
- Queue jobs and bulk sending
- Performance optimization
-
- 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
-
Always batch notifications
// Good ✅
NotificationController::sendNotification($msg, [1,2,3,4,5]);
// Bad ❌
foreach ($users as $user) {
NotificationController::sendNotification($msg, [$user]);
} -
Use queues for bulk sends
// Good ✅
SendBulkNotifications::dispatch($message);
// Bad ❌
foreach ($users as $user) {
NotificationService::send($message, [$user]);
} -
Keep payload small
- Max 4KB per notification
- Use IDs, not full objects
- Store large data in DB
Mobile App
-
Request permission at right time
// Good ✅ - When user enables feature
function handleEnableNotifications() {
Notifications.requestPermissionsAsync();
}
// Bad ❌ - On app launch
useEffect(() => {
Notifications.requestPermissionsAsync();
}, []); -
Clean up listeners
useEffect(() => {
const listener = Notifications.addNotificationReceivedListener(...);
return () => listener.remove(); // ✅ Always cleanup
}, []); -
Update token on launch
useEffect(() => {
registerForPushNotificationsAsync().then((token) => {
// Always re-register on app launch
updateTokenOnBackend(token);
});
}, []);
🔗 Related Resources
Internal Documentation
External Resources
- Expo Push Notifications
- Expo Push Tool - Test notifications
- Laravel Queues
- React Native Notifications
📞 Support
For issues or questions:
- Check the detailed documentation above
- Search for error messages in logs
- Test with Expo Push Tool
- 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.