Integração de Notificações Push entre o App do Passageiro e App do Motorista via Expo/PHP Backend e Firebase.
MySQL (federalprocom_app)
Expo Push API / FCM
< 15s (Com Alerta Sonoro)
O Firebase disponibiliza os seguintes serviços essenciais sem exigência de cartão de crédito cadastrado:
Envia Notificações Push em tempo real para motoristas e passageiros (alertas de viagens e aceite).
100% Gratuito / IlimitadoGerencia login via E-mail/Senha, Google e SMS (OTP).
Ilimitado (E-mail) / 10k SMS/mêsBanco NoSQL em tempo real para escutar posição no mapa ou status da viagem.
1 GB / 50k leituras/diaRastreia eventos de uso, telas acessadas e mede tempo de resposta das chamadas de API.
100% Gratuito / IlimitadoRelatórios automáticos em tempo real caso o app feche com erro nos celulares.
100% Gratuito / IlimitadoAltera variáveis do app (ex: tempo do modal) sem precisar reordenar update na Play Store.
100% Gratuito / IlimitadoExecute este comando na base de dados para permitir o armazenamento dos tokens de notificação por dispositivo.
ALTER TABLE motoristas ADD COLUMN push_token VARCHAR(255) NULL AFTER status_trabalho;
Código em React Native (Expo) para solicitar permissões e registrar o token no servidor no momento do login do motorista.
import * as Notifications from 'expo-notifications';
async function registrarPushToken(userId) {
const { status } = await Notifications.requestPermissionsAsync();
if (status !== 'granted') {
alert('Permissão de notificações negada!');
return;
}
// Obtém o token único do dispositivo
const tokenData = await Notifications.getExpoPushTokenAsync();
const token = tokenData.data;
// Envia o token para salvar no seu banco MySQL
await fetch('https://federalpro.com.br/api/salvar_token.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_id: userId, push_token: token })
});
}
Script backend responsável por registrar a corrida e enviar o alerta Push via Expo API aos motoristas ONLINE.
<?php
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json; charset=utf-8');
$host = 'localhost';
$user = 'federalprocom_adm';
$pass = 'vp@140698';
$dbname = 'federalprocom_app';
$conn = new mysqli($host, $user, $pass, $dbname);
$conn->set_charset("utf8mb4");
// Dados vindos do App do Passageiro
$input = json_decode(file_get_contents('php://input'), true);
$origem = $input['origem_endereco'];
$destino = $input['destino_endereco'];
$valor = $input['valor'];
$lat = $input['lat_origem'];
$lng = $input['lng_origem'];
$passageiro_id = $input['passageiro_id'];
// 1. Grava a corrida pendente no banco
$sql = "INSERT INTO corridas (passageiro_id, origem_endereco, destino_endereco, valor, status)
VALUES (?, ?, ?, ?, 'PENDENTE')";
$stmt = $conn->prepare($sql);
$stmt->bind_param("issd", $passageiro_id, $origem, $destino, $valor);
$stmt->execute();
$corrida_id = $stmt->insert_id;
$stmt->close();
// 2. Busca motoristas ONLINE que tenham um Push Token cadastrado
$sql_motoristas = "SELECT user_id, push_token FROM motoristas
WHERE status_trabalho = 'ONLINE'
AND push_token IS NOT NULL AND push_token != ''";
$result = $conn->query($sql_motoristas);
$tokens = [];
while ($row = $result->fetch_assoc()) {
$tokens[] = $row['push_token'];
}
// 3. Se houver motoristas disponíveis, dispara a Notificação Push via Expo/Firebase
if (!empty($tokens)) {
enviarPushExpo($tokens, [
'title' => '🚨 NOVA SOLICITAÇÃO DE VIAGEM!',
'body' => "Embarque: $origem | Valor: R$ " . number_format($valor, 2, ',', '.'),
'data' => [
'corrida_id' => $corrida_id,
'origem' => $origem,
'destino' => $destino,
'valor' => $valor
]
]);
}
echo json_encode(['sucesso' => true, 'corrida_id' => $corrida_id]);
$conn->close();
// Função auxiliar de envio de Notificação Push via Expo API
function enviarPushExpo($tokens, $mensagem) {
$payloads = [];
foreach ($tokens as $token) {
$payloads[] = [
'to' => $token,
'sound' => 'default',
'title' => $mensagem['title'],
'body' => $mensagem['body'],
'data' => $mensagem['data'],
'priority' => 'high'
];
}
$ch = curl_init('https://exp.host/--/api/v2/push/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payloads));
curl_exec($ch);
curl_close($ch);
}
?>
Ouvinte ativado em background/foreground para capturar a notificação, acionar som/vibração e exibir a modal de corrida.
import * as Notifications from 'expo-notifications';
// Configura o comportamento quando a notificação chega com o app aberto ou em background
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: false,
}),
});
useEffect(() => {
// Ouve a notificação recebida em tempo real
const subscription = Notifications.addNotificationReceivedListener(notification => {
const data = notification.request.content.data;
if (data && data.corrida_id) {
setCorridaPendente({
corrida_id: data.corrida_id,
origem_endereco: data.origem,
destino_endereco: data.destino,
valor: data.valor,
});
setShowCorridaModal(true);
setTempoRestante(15);
tocarAlertaCorrida();
}
});
return () => subscription.remove();
}, []);