PDO::ERRMODE_EXCEPTION]);
}
return $pdo;
}
class FirebaseAPI {
private $projectId;
private $accessToken;
public function __construct($projectId) {
$this->projectId = $projectId;
$pdo = getDB();
$stmt = $pdo->prepare("SELECT service_account_json FROM admin.firebase_projects WHERE project_id = ?");
$stmt->execute([$projectId]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row && $row['service_account_json']) {
$this->accessToken = $this->getAccessToken(json_decode($row['service_account_json'], true));
}
}
private function getAccessToken($saData) {
if (!$saData) return null;
$now = time();
$header = base64_encode(json_encode(['alg' => 'RS256', 'typ' => 'JWT']));
$claims = base64_encode(json_encode([
'iss' => $saData['client_email'],
'scope' => 'https://www.googleapis.com/auth/firebase.messaging https://www.googleapis.com/auth/identitytoolkit',
'aud' => 'https://oauth2.googleapis.com/token',
'iat' => $now, 'exp' => $now + 3600
]));
$signature = '';
openssl_sign("$header.$claims", $signature, $saData['private_key'], 'SHA256');
$jwt = "$header.$claims." . base64_encode($signature);
$ch = curl_init('https://oauth2.googleapis.com/token');
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query(['grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion' => $jwt])]);
$resp = json_decode(curl_exec($ch), true);
curl_close($ch);
return $resp['access_token'] ?? null;
}
public function sendPush($token, $title, $body) {
return $this->apiPost("https://fcm.googleapis.com/v1/projects/{$this->projectId}/messages:send",
['message' => ['token' => $token, 'notification' => ['title' => $title, 'body' => $body]]]);
}
private function apiPost($url, $data) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $this->accessToken, 'Content-Type: application/json'],
CURLOPT_POSTFIELDS => json_encode($data)
]);
$resp = curl_exec($ch);
curl_close($ch);
return json_decode($resp, true);
}
}
function ensureTables() {
$pdo = getDB();
$pdo->exec("CREATE TABLE IF NOT EXISTS admin.firebase_projects (
id SERIAL PRIMARY KEY, project_id VARCHAR(255) UNIQUE, project_name VARCHAR(255),
service_account_json TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)");
$pdo->exec("CREATE TABLE IF NOT EXISTS admin.firebase_tokens (
id SERIAL PRIMARY KEY, project_id VARCHAR(255), token TEXT, device_type VARCHAR(50) DEFAULT 'android',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)");
$pdo->exec("CREATE TABLE IF NOT EXISTS admin.firebase_notifications (
id SERIAL PRIMARY KEY, project_id VARCHAR(255), title VARCHAR(255), body TEXT,
target_type VARCHAR(50), tokens_count INTEGER DEFAULT 0, sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)");
}
if (isset($_GET['action']) || isset($_POST['action'])) {
header('Content-Type: application/json');
ensureTables();
$action = $_GET['action'] ?? $_POST['action'];
$pdo = getDB();
try {
switch ($action) {
case 'stats':
echo json_encode(['success' => true, 'stats' => [
'projects' => $pdo->query("SELECT COUNT(*) FROM admin.firebase_projects")->fetchColumn(),
'tokens' => $pdo->query("SELECT COUNT(*) FROM admin.firebase_tokens")->fetchColumn(),
'notifications' => $pdo->query("SELECT COUNT(*) FROM admin.firebase_notifications WHERE sent_at > NOW() - INTERVAL '24 hours'")->fetchColumn()
]]);
break;
case 'list_projects':
$projects = $pdo->query("SELECT id, project_id, project_name, created_at FROM admin.firebase_projects ORDER BY created_at DESC")->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($projects);
break;
case 'add_project':
$projectId = $_POST['project_id'] ?? '';
$projectName = $_POST['project_name'] ?? $projectId;
$serviceAccount = $_POST['service_account'] ?? '';
if ($projectId) {
$stmt = $pdo->prepare("INSERT INTO admin.firebase_projects (project_id, project_name, service_account_json) VALUES (?, ?, ?) ON CONFLICT (project_id) DO UPDATE SET project_name = ?, service_account_json = ?");
$stmt->execute([$projectId, $projectName, $serviceAccount, $projectName, $serviceAccount]);
}
echo json_encode(['success' => true]);
break;
case 'delete_project':
$id = $_POST['id'] ?? 0;
$pdo->exec("DELETE FROM admin.firebase_projects WHERE id = " . intval($id));
echo json_encode(['success' => true]);
break;
case 'list_tokens':
$projectId = $_GET['project_id'] ?? '';
$where = $projectId ? "WHERE project_id = " . $pdo->quote($projectId) : "";
$tokens = $pdo->query("SELECT * FROM admin.firebase_tokens $where ORDER BY created_at DESC LIMIT 100")->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($tokens);
break;
case 'add_token':
$projectId = $_POST['project_id'] ?? '';
$token = $_POST['token'] ?? '';
$deviceType = $_POST['device_type'] ?? 'android';
if ($projectId && $token) {
$stmt = $pdo->prepare("INSERT INTO admin.firebase_tokens (project_id, token, device_type) VALUES (?, ?, ?)");
$stmt->execute([$projectId, $token, $deviceType]);
}
echo json_encode(['success' => true]);
break;
case 'send_push':
$projectId = $_POST['project_id'] ?? '';
$title = $_POST['title'] ?? '';
$body = $_POST['body'] ?? '';
$tokenIds = json_decode($_POST['token_ids'] ?? '[]', true);
$sent = 0;
if ($projectId && $title && !empty($tokenIds)) {
$api = new FirebaseAPI($projectId);
$placeholders = implode(',', array_fill(0, count($tokenIds), '?'));
$stmt = $pdo->prepare("SELECT token FROM admin.firebase_tokens WHERE id IN ($placeholders)");
$stmt->execute($tokenIds);
$tokens = $stmt->fetchAll(PDO::FETCH_COLUMN);
foreach ($tokens as $token) {
$result = $api->sendPush($token, $title, $body);
if (!isset($result['error'])) $sent++;
}
$stmt = $pdo->prepare("INSERT INTO admin.firebase_notifications (project_id, title, body, target_type, tokens_count) VALUES (?, ?, ?, 'selected', ?)");
$stmt->execute([$projectId, $title, $body, $sent]);
}
echo json_encode(['success' => true, 'sent' => $sent]);
break;
default:
echo json_encode(['success' => false, 'error' => 'Unknown action']);
}
} catch (Exception $e) {
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
}
exit;
}
ensureTables();
?>
Firebase Manager - WEVAL SEND
Quick Actions
Projects
| Project ID | Name | Created | Actions |