Notificaciones push Firebase: de sitio web a app Flutter
Esta guía explica cómo integrar notificaciones en una app Wrapply: notificaciones locales, Firebase u OneSignal, permisos, sincronización del token del dispositivo y envío desde backend.
Comandos bridge para notificaciones
Estos son los comandos reales de notificaciones expuestos por la app Wrapply generada. Úsalos solo cuando el bridge esté listo y mantén un fallback para navegadores normales.
| Comando | Uso | Payload | Respuesta típica |
|---|---|---|---|
window.Wrapply.notifications.requestPermission(payload) | Solicita el permiso nativo de notificaciones | { provider: 'firebase' } | { ok, granted, permission } |
window.Wrapply.notifications.getToken(payload) | Lee el token del dispositivo para el proveedor seleccionado | { provider: 'firebase' } | { ok, token, selectedProvider } |
window.Wrapply.notifications.refreshToken(payload) | Fuerza la actualización del token | { provider: 'firebase' } | { ok, token } |
window.Wrapply.notifications.updateToken(payload) | Alias de refreshToken | { provider } | { ok, token } |
window.Wrapply.notifications.show(payload) | Muestra una notificación local inmediata | { title, body, data } | { ok, shown: true } |
window.Wrapply.notifications.getStatus(payload) | Comprueba permisos y estado del proveedor | { provider } | { ok, granted, configured } |
if (!Wrapply.notifications) return;
const permission = await Wrapply.notifications.requestPermission({ provider: 'firebase' });
if (!permission.ok || !permission.granted) return;
const token = await Wrapply.notifications.getToken({ provider: 'firebase' });
await fetch('/api/device-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: token.token, provider: token.selectedProvider })
});
});
title: 'Order updated',
body: 'Your order is ready',
data: JSON.stringify({ url: '/orders/123' })
});
Ejemplos de integración
Puedes usar el mismo patrón bridge en JavaScript, React, Vue, Angular, PHP/Laravel, WordPress o jQuery. Lo importante es esperar el bridge nativo antes de llamarlo.
JavaScript
if (!window.Wrapply?.notifications) return;
const permission = await window.Wrapply.notifications.requestPermission({ provider: 'firebase' });
if (!permission.ok || !permission.granted) return;
const result = await window.Wrapply.notifications.getToken({ provider: 'firebase' });
await fetch('/api/wrapply-event', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(result)
});
}
Hook React
export function useWrapplyBridge() {
const [ready, setReady] = useState(false);
useEffect(() => {
if (window.Wrapply?.__nativeBridgeReady) return setReady(true);
const onReady = () => setReady(true);
window.addEventListener('wrapplyNativeBridgeReady', onReady);
return () => window.removeEventListener('wrapplyNativeBridgeReady', onReady);
}, []);
return { ready, Wrapply: ready ? window.Wrapply : null };
}
Composable Vue
export function useWrapplyBridge() {
const ready = ref(false);
onMounted(() => {
if (window.Wrapply?.__nativeBridgeReady) ready.value = true;
else window.addEventListener('wrapplyNativeBridgeReady', () => ready.value = true, { once: true });
});
return { ready };
}
Servicio Angular
export class WrapplyBridgeService {
async callNative(payload = {}) {
if (!window.Wrapply?.notifications) return { ok: false, error: 'Bridge unavailable' };
return window.Wrapply.notifications.getStatus(payload);
}
}
jQuery
if (!window.Wrapply?.notifications) return;
const result = await window.Wrapply.notifications.getStatus({});
$('#wrapply-output').text(JSON.stringify(result, null, 2));
});
CMS / plantilla backend
<script>
window.addEventListener('wrapplyNativeBridgeReady', function () {
document.body.classList.add('wrapply-native-app');
});
</script>
Cómo funcionan las notificaciones en apps Wrapply
Las notificaciones no son solo un botón en la app. Requieren permiso, proveedor, token del dispositivo y normalmente un backend o Cloud Function para enviar mensajes remotos.
| Paso | Llamada bridge | Qué hace |
|---|---|---|
| 1 | requestPermission | Solicita permiso antes de mostrar notificaciones |
| 2 | getToken | Lee el token local/Firebase/OneSignal y lo envía al backend |
| 3 | refreshToken / updateToken | Actualiza el token después de login, logout, cambio de cuenta o reinstalación |
| 4 | show | Muestra una notificación local inmediata desde el sitio dentro de la app |
| 5 | getStatus | Comprueba permiso y configuración antes de mostrar acciones UI |
Proveedores de notificaciones
El sitio puede elegir el proveedor de notificaciones en cada llamada. Wrapply incluye solo el proveedor seleccionado en la app generada.
| Proveedor | Uso | Configuración requerida | Nota importante |
|---|---|---|---|
| local | Default seguro, token local guardado en shared preferences | Sin archivo externo | Útil para pruebas/sesión; no es un token push remoto real |
| firebase | Proveedor Firebase Cloud Messaging | android/app/google-services.json y opcional ios/Runner/GoogleService-Info.plist | Si faltan archivos, devuelve ok:false/configured:false |
| onesignal | Proveedor OneSignal | OneSignal App ID en configuración/build | Requiere setup OneSignal antes de enviar push remotas |
Ejemplos por tipo de código
Usa las mismas llamadas bridge desde JavaScript, React, Vue, Angular o CMS. Lo importante es esperar wrapplyNativeBridgeReady, pedir permiso, leer el token y enviarlo al backend.
if (window.Wrapply && window.Wrapply.__nativeBridgeReady) {
callback(window.Wrapply);
return;
}
window.addEventListener("wrapplyNativeBridgeReady", () => {
callback(window.Wrapply);
}, { once: true });
}
const permission = await Wrapply.notifications.requestPermission({ provider: "firebase" });
if (!permission.ok || !permission.granted) return;
const token = await Wrapply.notifications.getToken({ provider: "firebase" });
await fetch("/api/device-token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: token.token, provider: token.provider })
});
await Wrapply.notifications.show({
title: "Welcome",
body: "Notifications are enabled for this app.",
data: JSON.stringify({ url: window.location.href })
});
});