I'm creating web app using Django, and trying to send push notification via firebase API. It's working when user is on page that registers firebase-messaging-sw.js, but in background no notification is coming, even though no error was raised.
def send_fcm_notification(device_token, title, body, data=None, click_action=None): headers = {"Authorization": f"Bearer {get_access_token()}","Content-Type": "application/json", } data = {"message": {"token": device_token, # Use "topic": "your-topic" to send to a topic"notification": {"title": title,"body": body, },"data": data or {},"android": {"priority": "high" },"apns": {"payload": {"aps": {"alert": {"title": title,"body": body } } } } } } response = requests.post(FCM_ENDPOINT, headers=headers, data=json.dumps(data)) return response.json()
SW
importScripts("https://www.gstatic.com/firebasejs/11.2.0/firebase-app-compat.js");importScripts("https://www.gstatic.com/firebasejs/11.2.0/firebase-messaging-compat.js");// Firebase Configuration (Same as in your main script)const firebaseConfig = { //myconfig data};// Initialize Firebasefirebase.initializeApp(firebaseConfig);const messaging = firebase.messaging();self.addEventListener('notificationclick', (event) => { event.notification.close(); // CLosing the notification when clicked const urlToOpen = event?.notification?.data?.url || 'https://www.test.com/'; // Open the URL in the default browser. event.waitUntil( clients.matchAll({ type: 'window', }) .then((windowClients) => { // Check if there is already a window/tab open with the target URL for (const client of windowClients) { if (client.url === urlToOpen && 'focus' in client) { return client.focus(); } } // If not, open a new window/tab with the target URL if (clients.openWindow) { return clients.openWindow(urlToOpen); } }) ); });// Handle background notificationsmessaging.onBackgroundMessage((payload) => { console.log("Received background message:", payload); self.registration.showNotification(payload.notification.title, { body: payload.notification.body, icon: payload.notification.image || "/static/img/favicon.ico", data: { url: payload?.data?.url || 'https://www.test.com/'}, });});
index.html
<script type="module"> // Import Firebase SDK import { initializeApp } from "https://www.gstatic.com/firebasejs/11.2.0/firebase-app.js"; import { getMessaging, getToken, onMessage } from "https://www.gstatic.com/firebasejs/11.2.0/firebase-messaging.js"; // Firebase Configuration const firebaseConfig = { //my config data }; // Initialize Firebase const app = initializeApp(firebaseConfig); const messaging = getMessaging(app); // Get CSRF token from Django cookies function getCSRFToken() { const cookieValue = document.cookie .split('; ') .find(row => row.startsWith('csrftoken=')) ?.split('=')[1]; return cookieValue || ''; } // Register Firebase Service Worker navigator.serviceWorker.register("/static/firebase-messaging-sw.js") .then((registration) => { console.log("Service Worker registered:", registration); // Request Notification Permission Notification.requestPermission().then(permission => { if (permission === 'granted') { console.log("Notification permission granted."); // Get FCM Token getToken(messaging, { vapidKey: 'MY-VAPIDKEY', serviceWorkerRegistration: registration // Required for service worker }).then((currentToken) => { if (currentToken) { console.log("FCM Token:", currentToken); // Send the token to Django backend fetch('/register-device/', { method: 'POST', headers: {'Content-Type': 'application/json','X-CSRFToken': getCSRFToken(), }, body: JSON.stringify({ token: currentToken, platform: 'web' }) }).then(response => response.json()) .then(data => console.log("Token registered:", data)) .catch(error => console.error("Error sending token:", error)); } else { console.log("No registration token available."); } }).catch((err) => { console.log('Error getting token:', err); }); } else { console.log("Notification permission denied."); } }); }).catch((err) => { console.log("Service Worker registration failed:", err); }); // Handle Incoming Foreground Messages onMessage(messaging, (payload) => { console.log('Foreground message received:', payload); // Show a real notification when a message arrives new Notification(payload.notification.title, { body: payload.notification.body, icon: payload.notification.image || "/static/img/favicon.ico" }); });</script>
I think only reason why it is working while page is open is onMessage function in index.html