Brazil's biggest MU Online portal — since 2003
Tutorial Advanced Web

How to implement push notifications on your MU Online server's mobile app

Implement real push notifications on your MU Online server's mobile app or PWA, covering Firebase Cloud Messaging, segmentation by game event, GameServer integration, and best practices to avoid permission opt-outs.

RO Rodrigo · Updated on Feb 15, 2023 · ⏱ 16 min read
Quick answer

Push notifications turn your MU Online server's portal or app into a real-time communication channel, able to alert players about a Castle Siege starting, a rare event opening, or a flash shop promotion — even with the browser or app closed. Unlike email or Discord, push arrives instantly on the dev

Push notifications turn your MU Online server's portal or app into a real-time communication channel, able to alert players about a Castle Siege starting, a rare event opening, or a flash shop promotion — even with the browser or app closed. Unlike email or Discord, push arrives instantly on the device's screen, with a much higher attention rate. Implementing this correctly requires integrating Firebase Cloud Messaging, setting up a Service Worker in the PWA, connecting real server events to send triggers, and above all respecting player preference to avoid mass permission opt-outs. This tutorial covers the full implementation, from scratch through integration with GameServer events.

Why push notifications and not just email or Discord

Each communication channel plays a different role in player retention. Email is asynchronous and good for longer content (patch notes, weekly summaries); Discord depends on the player having notifications enabled for that specific server; push lands directly on the phone's lock screen or as an OS-level notification, with much faster reaction time. For time-sensitive alerts — "Castle Siege starts in 10 minutes," "Kundun Invasion active now" — push is the only channel with a real chance of the player seeing it in time to act.

Choosing between PWA and native app

Before implementing push, decide on the platform. For most MU Online servers, a well-configured PWA is the most efficient choice:

CriterionPWA (installable site)Native app (Android/iOS)
Development costLow (reuses the existing site)High (separate codebase)
App store publishingNot requiredRequires a developer account and approval
Push support on AndroidFullFull
Push support on iOSPartial (Safari 16.4+, requires home-screen install)Full
MaintenanceA single codebaseTwo codebases (or a hybrid framework)

For most cases, start with a PWA and only consider a native app if your iOS player base is large enough to justify the extra cost.

Setting up Firebase Cloud Messaging

Firebase Cloud Messaging (FCM) is the most widely used sending service, being free and covering Android, iOS, and Web. The initial setup steps:

  1. Create a project in the Firebase console (console.firebase.google.com).
  2. Add a Web app to the project and copy the credentials (apiKey, projectId, messagingSenderId, etc.).
  3. Generate a VAPID key pair in the Cloud Messaging tab, required for Web Push.
  4. Install the SDK in the site's project (npm install firebase).

Example initial setup in a Next.js project:

// lib/firebase.js
import { initializeApp } from 'firebase/app';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';

const firebaseConfig = {
  apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
  projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
  messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_SENDER_ID,
  appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
};

const app = initializeApp(firebaseConfig);
export const messaging = typeof window !== 'undefined' ? getMessaging(app) : null;

Registering the Service Worker

Push only works with a registered Service Worker, responsible for receiving the notification even with the tab/app closed:

// public/firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/10.7.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/10.7.0/firebase-messaging-compat.js');

firebase.initializeApp({
  apiKey: 'SUA_API_KEY',
  projectId: 'SEU_PROJECT_ID',
  messagingSenderId: 'SEU_SENDER_ID',
  appId: 'SEU_APP_ID',
});

const messaging = firebase.messaging();

messaging.onBackgroundMessage((payload) => {
  self.registration.showNotification(payload.notification.title, {
    body: payload.notification.body,
    icon: '/icons/icon-192.png',
  });
});

This file needs to sit in the site's public root (public/firebase-messaging-sw.js), directly accessible via URL, so the browser can register it.

Asking the player for permission correctly

Asking for notification permission the moment a player first visits the site is the most common mistake and the main cause of rejection. The correct approach is contextual:

  • Wait until the player takes a relevant action (e.g., signs up, visits the events page) before asking for permission.
  • Explain the value before the browser's native prompt: a small banner "Want to be notified when Castle Siege starts? Turn on notifications" before triggering the actual permission API.
  • Never insist again if the player declines — respect their choice and offer the option to enable it later in profile settings.
async function solicitarPermissao() {
  const permissao = await Notification.requestPermission();
  if (permissao === 'granted') {
    const token = await getToken(messaging, { vapidKey: 'SUA_VAPID_KEY' });
    // enviar token para o backend, associado ao jogador logado
    await fetch('/api/push/registrar', {
      method: 'POST',
      body: JSON.stringify({ token }),
    });
  }
}

Segmenting notifications by event type

Just like with the newsletter, notifying everyone about everything causes fatigue and permission opt-outs. Structure categories the player can choose from:

CategoryContent exampleTypical frequency
PvP eventsCastle Siege start, guild war1-2x per week
Server PvE eventsInvasion, Golden Invasion, special Chaos CastleDaily, at fixed times
Shop and promotionsFlash discount, new credit packageOccasional
Maintenance/infraScheduled downtime notice, patch updateOnly when needed

Store each player's preference (which categories they accepted) in a database table on the site, tied to the push token, and always segment sends by that preference.

Integrating real GameServer events into the trigger

The most powerful (and most work-intensive) part is connecting the GameServer itself to the push system, to notify the exact moment a game event starts, not an approximate fixed time. A common architecture:

  1. A small intermediary service monitors the GameServer logs or periodically queries the game's database (every 10-30 seconds), looking for a change in event state (e.g., the EventStatus column in the event configuration table).
  2. Upon detecting an event changed from "closed" to "open," this service calls the site's backend API.
  3. The site's backend queries the push token table segmented by the matching category and sends the notification via the Firebase Admin SDK API.

Simplified example of the send on the backend, using Firebase Admin:

// server: dispara notificação quando o serviço detecta evento aberto
const admin = require('firebase-admin');

async function notificarEvento(categoria, titulo, corpo) {
  const tokens = await buscarTokensPorCategoria(categoria); // consulta ao banco
  await admin.messaging().sendEachForMulticast({
    tokens,
    notification: { title: titulo, body: corpo },
  });
}

// exemplo de chamada quando o serviço detecta Devil Square aberto
notificarEvento('eventos_pve', 'Devil Square está aberto!', 'Corra para participar antes que feche.');

Testing on different platforms

Before rolling out to all players, test the full flow on each target environment:

  • Android (Chrome): full support, test with the app/PWA in the background and fully closed.
  • iOS (Safari): requires the player to have installed the PWA to the home screen (Add to Home Screen); push doesn't work with just the browser open normally.
  • Desktop (Chrome/Edge/Firefox): full support, useful for players who follow along from their computer.

Clearly document the iOS limitations for players on the site itself, avoiding support tickets from those who couldn't enable notifications because they hadn't installed the PWA correctly.

Common errors and fixes

SymptomLikely causeFix
Permission denied by most playersPermission requested too early/aggressivelyUse a contextual banner before the native prompt
Notifications don't arrive on iOSPWA not installed to the home screenGuide manual installation, a Safari limitation
Service Worker doesn't registerFile outside the public root or wrong pathConfirm public/firebase-messaging-sw.js is accessible via URL
Many players disable notifications after a short timeGeneric sending with no segmentationImplement categories and respect player preference
Event notification arrives lateIntermediary service's polling interval too longReduce check interval or use a direct database trigger

Push notifications checklist

  • Decision made between PWA and native app, based on the player base.
  • Firebase project configured with generated VAPID keys.
  • Service Worker registered and accessible at the site's public root.
  • Contextual permission request flow implemented.
  • Notification categories defined and preferences saved per player.
  • Integration between real GameServer events and push sending.
  • Tests performed on Android, iOS (PWA installed), and desktop.

With push working end to end, the server gains a real-time communication channel that complements email and Discord — it's worth reviewing the MU Online server setup tutorial to make sure the backend infrastructure supports this GameServer integration without performance bottlenecks.

Frequently asked questions

Do I need a native app, or can I just use the site (PWA)?

A well-configured PWA (Progressive Web App) already supports push notifications on both Android and, with limitations, iOS from recent Safari versions onward. For most MU Online servers, a PWA is enough and much cheaper to maintain than a native app published on app stores.

Which service should I use to send push notifications?

Google's Firebase Cloud Messaging (FCM) is the industry standard, free for practically any volume a MU Online server would need, and works for both native Android/iOS apps and PWAs via Web Push.

How do I keep players from disabling notifications due to excessive sending?

Segment by event type and let players choose which categories they want to receive (Castle Siege, invasions, shop promotions). Generic, excessive notifications are the main cause of mass permission opt-outs.

Is it possible to notify the player in real time when a game event starts (e.g., Devil Square opens)?

Yes, by integrating the GameServer (or an intermediary service that reads the server's logs/events) with a webhook that fires the push notification as soon as the event starts. This requires a small integration service between the emulator and Firebase.

Do push notifications work with the browser closed?

Yes, that's precisely push's advantage over regular in-app notifications. A Service Worker registered in the browser or device receives the notification even with the site/app closed, as long as the user previously granted permission.

RO
Founder & editor-in-chief

Rodrigo has run ViciadosMU since the portal's early days. A specialist in MU Online server creation and administration, game history and the evolution of the seasons — he wrote much of the archive before 2024.

Keep reading

Related articles