Skip to main content

Client SDK

Alpha

This feature is in alpha. APIs and behavior may change without notice. Not recommended for production use.

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.fun');

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