Expo Mobile
Ao abrir o app ou autenticar, o dispositivo solicita permissão e gera o token de Push ativo.
// notificationService.js
import * as Notifications from 'expo-notifications';
export async function getPushToken() {
const { status } = await Notifications.requestPermissionsAsync();
if (status !== 'granted') return null;
// Suporta Expo Go e Builds Nativas
const tokenData = await Notifications.getExpoPushTokenAsync({
projectId: 'SEU_EXPO_PROJECT_ID'
});
return tokenData.data; // ExponentPushToken[...]
}
Firestore BD
O token obtido é gravado no documento único do usuário logado na coleção users.
// AuthContext.js (No Login)
import { doc, setDoc } from 'firebase/firestore';
async function bindUserToken(userId, pushToken) {
const userRef = doc(db, 'users', userId);
await setDoc(userRef, {
pushToken: pushToken,
updatedAt: new Date().toISOString()
}, { merge: true });
}
Backend Node.js
O servidor recupera o token via userId, grava o histórico no banco e despacha o Push.
// server.js
async function sendNotification(userId, title, body) {
// 1. Busca Token
const userDoc = await db.collection('users').doc(userId).get();
const token = userDoc.data()?.pushToken;
// 2. Salva Histórico no Firestore
const notifRef = await db.collection('notifications').add({
userId, title, body, read: false, createdAt: new Date()
});
// 3. Envia para API Expo (Bridge para FCM/APNs)
await fetch('https://exp.host/--/api/v2/push/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ to: token, title, body })
});
}