Federal Driver Systems

Conexão Push em Tempo Real

Integração de Notificações Push entre o App do Passageiro e App do Motorista via Expo/PHP Backend e Firebase.

Banco de Dados

MySQL (federalprocom_app)

Serviço Push

Expo Push API / FCM

Tempo de Resposta

< 15s (Com Alerta Sonoro)

Recursos Gratuitos do Firebase (Plano Spark - Sem Cartão)

PLANO SPARK

O Firebase disponibiliza os seguintes serviços essenciais sem exigência de cartão de crédito cadastrado:

Cloud Messaging (FCM)

Envia Notificações Push em tempo real para motoristas e passageiros (alertas de viagens e aceite).

100% Gratuito / Ilimitado
Firebase Authentication

Gerencia login via E-mail/Senha, Google e SMS (OTP).

Ilimitado (E-mail) / 10k SMS/mês
Cloud Firestore

Banco NoSQL em tempo real para escutar posição no mapa ou status da viagem.

1 GB / 50k leituras/dia
Analytics & Performance

Rastreia eventos de uso, telas acessadas e mede tempo de resposta das chamadas de API.

100% Gratuito / Ilimitado
Crashlytics

Relatórios automáticos em tempo real caso o app feche com erro nos celulares.

100% Gratuito / Ilimitado
Remote Config

Altera variáveis do app (ex: tempo do modal) sem precisar reordenar update na Play Store.

100% Gratuito / Ilimitado
O que Exige Cartão / Plano Pago (Plano Blaze)?
  • Cloud Functions: Execução de código Node.js no servidor Firebase (recomenda-se manter no seu PHP/MySQL).
  • SMS Acima de 10.000/mês: Excede a cota gratuita no Firebase Authentication.
1

Alteração no Banco de Dados (MySQL)

PENDENTE

Execute este comando na base de dados para permitir o armazenamento dos tokens de notificação por dispositivo.

SQL Query
ALTER TABLE motoristas ADD COLUMN push_token VARCHAR(255) NULL AFTER status_trabalho;
2

Registro do Push Token no App do Motorista

PENDENTE

Código em React Native (Expo) para solicitar permissões e registrar o token no servidor no momento do login do motorista.

JavaScript (React Native)
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 })
  });
}
3

Script PHP do Servidor (solicitar_corrida.php)

PENDENTE

Script backend responsável por registrar a corrida e enviar o alerta Push via Expo API aos motoristas ONLINE.

PHP Backend
<?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);
}
?>
4

Escuta do Push no App do Motorista (HomeScreen.js)

PENDENTE

Ouvinte ativado em background/foreground para capturar a notificação, acionar som/vibração e exibir a modal de corrida.

JavaScript (HomeScreen.js)
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();
}, []);
Código copiado para a área de transferência!