Skip to main content

Client SDK

Push notification setup varies significantly per platform. Select your platform below for the complete integration guide.

All platforms follow the same pattern: inject a token providerregisterhandle messages. The SDK automatically unregisters when the user signs out.

Prerequisites

  1. Complete the Firebase setup — register a Web app and get your VAPID key.
  2. Install dependencies:
npm install firebase @edgebase/web

Setup

1. Initialize Firebase

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

const firebaseApp = initializeApp({
apiKey: "...",
authDomain: "...",
projectId: "my-firebase-project",
messagingSenderId: "...",
appId: "...",
});

const messaging = getMessaging(firebaseApp);

2. Create a Service Worker

Create firebase-messaging-sw.js in your public root directory:

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

firebase.initializeApp({
apiKey: "...",
authDomain: "...",
projectId: "my-firebase-project",
messagingSenderId: "...",
appId: "...",
});

const messaging = firebase.messaging();

messaging.onBackgroundMessage((payload) => {
const { title, body } = payload.notification || {};
self.registration.showNotification(title || 'New notification', {
body: body || '',
icon: '/icon.png',
data: payload.data,
});
});

self.addEventListener('notificationclick', (event) => {
event.notification.close();
event.waitUntil(
clients.matchAll({ type: 'window', includeUncontrolled: true }).then((windowClients) => {
if (windowClients.length > 0) {
windowClients[0].focus();
} else {
clients.openWindow('/');
}
})
);
});

The Service Worker must be served from your site's root path (e.g., https://yoursite.com/firebase-messaging-sw.js).

3. Set Token Provider

import { createClient } from '@edgebase/web';

const client = createClient('https://my-app.edgebase.dev');

client.push.setTokenProvider(async () => {
const token = await getToken(messaging, {
vapidKey: 'YOUR_VAPID_KEY',
});
return token;
});

4. Register

await client.push.register();

// With metadata
await client.push.register({ metadata: { theme: 'dark' } });

Permission Handling

register() automatically requests permission if the user hasn't been asked yet. However, you should check and handle permission status explicitly for a better user experience.

Check permission status:

const status = client.push.getPermissionStatus();
// 'granted' | 'denied' | 'notDetermined'

Request permission manually (before register):

const result = await client.push.requestPermission();
if (result === 'granted') {
await client.push.register();
} else {
// Show a message explaining why notifications are useful
}
Best Practice

Avoid requesting permission on page load. Instead, show a pre-permission prompt (e.g., a banner or button) explaining why notifications are useful, and only call register() when the user opts in. Browsers may block the prompt entirely if triggered without a user gesture.

Permission Denied

If the user has denied permission, register() returns silently without throwing an error. The browser will not show the permission prompt again — the user must manually re-enable notifications in browser settings. Use getPermissionStatus() to detect this and show appropriate UI guidance.

Handle Messages

Foreground:

onMessage(messaging, (payload) => {
console.log('Foreground message:', payload);
});

// Or listen via EdgeBase
client.push.onMessage((message) => {
console.log('Push:', message.title, message.body);
});

Notification Tap:

client.push.onMessageOpenedApp((message) => {
const chatId = message.data?.chatId;
if (chatId) {
window.location.href = `/chat/${chatId}`;
}
});

Topic Subscription

Web topic subscriptions go through the EdgeBase server:

await client.push.subscribeTopic('news');
await client.push.unsubscribeTopic('news');

Unregister

await client.push.unregister();

Browser Support

Chrome 50+, Firefox 44+, Edge 17+, Safari 16+, Opera 42+

API Reference

MethodDescription
setTokenProvider(provider)Set FCM token acquisition function
register({metadata?})Request permission, get token, register
unregister(deviceId?)Unregister device
subscribeTopic(topic)Subscribe to an FCM topic (server-side)
unsubscribeTopic(topic)Unsubscribe from an FCM topic (server-side)
onMessage(callback)Listen for foreground messages
onMessageOpenedApp(callback)Listen for notification tap events
getPermissionStatus()Returns 'granted', 'denied', or 'notDetermined'
requestPermission()Request notification permission