feat: Firebase Cloud Messaging push notifications

Backend:
- New user_fcm_tokens table (migration 010) for storing device tokens
- FCMService sends push via Firebase HTTP legacy API (server key from .env)
- POST /api/fcm/register endpoint for Android to register its FCM token
- AdminController::sendNotification() triggers FCM push after DB insert
- FCM config added to config.php

Android:
- Firebase Cloud Messaging service (ServerManagerFirebaseService)
  receives push notifications and shows them via NotificationHelper
- FCM token registered with backend on new token and on login
- google-services.json template (must be replaced with real Firebase config)
- firebase-setup.sh script with configuration instructions
- FCM dependency + google-services plugin added to Gradle
- Bump to v1.8.0 (versionCode 12)
This commit is contained in:
2026-06-13 12:37:40 -04:00
parent bdc4d73d89
commit 136eebc4c3
17 changed files with 383 additions and 1 deletions

View File

@@ -13,6 +13,7 @@ use ServerManager\Services\MonitoringService;
use ServerManager\Services\SSHService;
use ServerManager\Services\AuditService;
use ServerManager\Services\PermissionValidator;
use ServerManager\Services\FCMService;
use ServerManager\Models\CommandHistory;
use ServerManager\Core\Validator;
@@ -696,6 +697,34 @@ class ApiController
$this->view->json(['success' => true]);
}
public function registerFcmToken(): void
{
$user = $this->authenticateRequest();
$input = json_decode(file_get_contents('php://input'), true) ?? $_POST;
$token = $input['token'] ?? '';
if (empty($token)) {
$this->view->json(['error' => 'Token is required'], 400);
}
$db = \ServerManager\Core\Database::getInstance();
$existing = $db->fetch(
'SELECT id FROM user_fcm_tokens WHERE user_id = ? AND token = ?',
[(int) $user['id'], $token]
);
if (!$existing) {
$db->insert('user_fcm_tokens', [
'user_id' => (int) $user['id'],
'token' => $token,
'created_at' => date('Y-m-d H:i:s'),
]);
}
$this->view->json(['success' => true]);
}
public function serverServices(int $id): void
{
$user = $this->authenticateRequest();