0

I'm working on a Next.js PWA using Firebase Cloud Messaging (FCM). I have implemented a service worker to handle background push notifications, and I'm experiencing inconsistent behavior across platforms when the user clicks on the notification:

What works:

  • iOS (Safari installed PWA): notification opens the correct deep link inside the app.

  • Web (desktop): notification opens the expected URL as well.

What fails (Android):

  • If the PWA is in foreground, the notification works as expected — the app navigates to the conversation screen.

  • If the PWA is in the background, tapping the notification does nothing.

  • If the PWA is closed, tapping the notification also does nothing — the app doesn't open at all.

However, if the PWA was in the background and I manually open it after tapping the notification, it does redirect correctly to the conversation. So the logic is working — it's just not opening the app.

My Setup firebase-messaging-sw.js:

self.addEventListener("notificationclick", (event) => {
  event.preventDefault();
  console.log("[SW] notificationclick received", event.notification.data);

  const url = event.notification.data?.url || "/";
  console.log("[SW] will open URL:", url);

  event.notification.close();

  event.waitUntil(
    clients
      .matchAll({ type: "window", includeUncontrolled: true })
      .then((windowClients) => {
        console.log("[SW] windowClients:", windowClients.length);
        for (const client of windowClients) {
          // Si encuentras un cliente con tu dominio, úsalo
          if (client.url.startsWith(self.location.origin)) {
            console.log("[SW] navigating existing client:", client.url);
            return client
              .navigate(url)
              .then((navResult) => {
                console.log("[SW] navigate() result:", navResult);
                return client.focus();
              });
          }
        }
        // Si no hay ninguno, abre uno nuevo
        console.log("[SW] no matching client, openWindow:", url);
        return clients.openWindow(url);
      })
      .catch((err) => {
        console.error("[SW] error in notificationclick handler:", err);
        // como fallback abre siempre algo
        return clients.openWindow(url);
      })
  );
});

In the app (Next.js), I handle redirection with a hook that is called on root layout:

// hooks/useRedirectFromNotification.ts
useEffect(() => {
  const qs = new URLSearchParams(window.location.search);
  const to = qs.get("redirect");
  if (to) {
    setTimeout(() => router.replace(to), 300);
    window.history.replaceState({}, "", window.location.pathname);
  }
}, []);

useEffect(() => {
  if (!("serviceWorker" in navigator)) return;
  const handler = (e: MessageEvent) => {
    const data = e.data || {};
    if (data.type === "NAVIGATE" && data.url) {
      router.push(data.url);
    }
  };
  navigator.serviceWorker.addEventListener("message", handler);
  return () => navigator.serviceWorker.removeEventListener("message", handler);
}, []);

My manifest.json includes:

{
  "start_url": "/",
  "scope": "/",
  "display": "standalone",
  "gcm_sender_id": "726337043778"
}

What I tried:

  • Using .navigate(url) directly — doesn’t work in Android.

  • Only using .openWindow() — opens in Chrome browser, not PWA.

  • Fallback with /?redirect=... and postMessage — logic works but app doesn’t open.

  • Setting display: "standalone" and proper start_url, scope, theme_color in manifest.json.

My question:

  • Why does clicking the notification not open the PWA on Android when it's in the background or closed?
  • Is there a reliable way to force the Android PWA (installed via Chrome) to launch from a push notification?

Any insight or workaround would be appreciated.Thank you in advance!

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.