From 74633bcf2ce46e69259088ab85c9f8591047b2a4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 5 Jun 2025 15:58:56 +0000 Subject: [PATCH] feat: Integrate Firebase Cloud Messaging (FCM) I've added Firebase Cloud Messaging capabilities to your web application. Here are the key changes: - I created `public/firebase-messaging-sw.js`: This handles background notifications, initializing Firebase and displaying notifications when the app is not in focus. - I modified `src/app.ts`: - I integrated the FCM SDK to request notification permissions from you. - I retrieve and log/display the FCM registration token. - I added a handler for foreground messages, displaying them directly in the app. - I included a placeholder for the VAPID key, which you must configure. - I updated `index.html`: - I added new UI elements to display the FCM registration token and any notifications received while the app is in the foreground. Here are the post-integration steps for you: - Replace the placeholder VAPID key in `src/app.ts` with your actual key from the Firebase console. - Ensure your Firebase project is configured for FCM, including the VAPID key. - Test by sending messages via the Firebase console. --- index.html | 8 +++++ public/firebase-messaging-sw.js | 55 +++++++++++++++++++++++++++++++++ src/app.ts | 48 ++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 public/firebase-messaging-sw.js diff --git a/index.html b/index.html index ba1781b..7199938 100644 --- a/index.html +++ b/index.html @@ -9,6 +9,14 @@

VinF - Hybrid Inference - Bug Bash

+
+

FCM Status

+

FCM Token: Waiting...

+

Foreground Notifications:

+
+ +
+


Text Only Input

diff --git a/public/firebase-messaging-sw.js b/public/firebase-messaging-sw.js new file mode 100644 index 0000000..23623ff --- /dev/null +++ b/public/firebase-messaging-sw.js @@ -0,0 +1,55 @@ +// Import the Firebase app and messaging modules +import { initializeApp } from 'firebase/app'; +import { getMessaging, onBackgroundMessage } from 'firebase/messaging/sw'; // Note: using firebase/messaging/sw + +// Your web app's Firebase configuration (taken from src/app.ts) +// IMPORTANT: Make sure this config is identical to the one in src/app.ts +const firebaseConfig = { + apiKey: "*", // Replace with your actual apiKey if not using a placeholder + authDomain: "vertexaiinfirebase-test.firebaseapp.com", + projectId: "vertexaiinfirebase-test", + storageBucket: "vertexaiinfirebase-test.firebasestorage.app", + messagingSenderId: "857620473716", + appId: "1:857620473716:web:8c803ada68ede9b2bb6e21" +}; + +// Initialize Firebase +const app = initializeApp(firebaseConfig); +const messaging = getMessaging(app); + +onBackgroundMessage(messaging, (payload) => { + console.log('[firebase-messaging-sw.js] Received background message ', payload); + + // Customize notification here + const notificationTitle = payload.notification?.title || 'Background Message'; + const notificationOptions = { + body: payload.notification?.body || 'Something happened in the background', + icon: payload.notification?.icon || '/images/dog.jpg' // Default icon + }; + + self.registration.showNotification(notificationTitle, notificationOptions); +}); + +// Optional: Add event listeners for notification click +self.addEventListener('notificationclick', function(event) { + console.log('[firebase-messaging-sw.js] Notification click Received.', event.notification); + event.notification.close(); + + // Example: Focus or open a window + // event.waitUntil( + // clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) { + // if (clientList.length > 0) { + // let client = clientList[0]; + // for (let i = 0; i < clientList.length; i++) { + // if (clientList[i].focused) { + // client = clientList[i]; + // } + // } + // return client.focus(); + // } + // return clients.openWindow('/'); // Open your app's root page + // }) + // ); +}); + +console.log('[firebase-messaging-sw.js] Service worker registered and listening for background messages.'); diff --git a/src/app.ts b/src/app.ts index 1f785b6..123c9fd 100644 --- a/src/app.ts +++ b/src/app.ts @@ -8,6 +8,7 @@ import { import { initializeApp } from "firebase/app"; +import { getMessaging, getToken, onMessage } from "firebase/messaging"; const firebaseConfig = { @@ -21,6 +22,7 @@ const firebaseConfig = { // Initialize Firebase const app = initializeApp(firebaseConfig); +const messaging = getMessaging(app); // Initialize the Vertex AI service // const vertexAI = getVertexAI(app); @@ -203,7 +205,53 @@ async function fileToGenerativePart(file: Blob) { // --- Event Listener Setup --- + +async function requestNotificationPermissionAndToken() { + console.log("Requesting notification permission..."); + try { + const permission = await Notification.requestPermission(); + if (permission === "granted") { + console.log("Notification permission granted."); + // TODO: Replace 'YOUR_VAPID_KEY' with your actual VAPID key from the Firebase console. + // You will need to generate this key in the Firebase console under Project settings > Cloud Messaging > Web configuration. + const currentToken = await getToken(messaging, { vapidKey: "YOUR_VAPID_KEY_REPLACE_ME" }); + if (currentToken) { + console.log("FCM Token:", currentToken); + // You would typically send this token to your server to store it. + // For display in this example, let's add it to a DOM element if it exists. + const tokenElement = document.getElementById('fcmToken'); + if (tokenElement) { + tokenElement.textContent = `FCM Token: ${currentToken}`; + } + } else { + console.log("No registration token available. Request permission to generate one."); + } + } else { + console.log("Unable to get permission to notify."); + } + } catch (error) { + console.error("An error occurred while requesting permission or getting token: ", error); + } +} + +onMessage(messaging, (payload) => { + console.log("Message received in foreground: ", payload); + // Customize notification handling here. + // For example, show an alert or update the UI. + alert(`Foreground message received: ${payload.notification?.title || 'New Message'}`); + + // You could also display this information in a dedicated part of your UI. + const notificationDisplay = document.getElementById('foregroundNotificationDisplay'); + if (notificationDisplay) { + notificationDisplay.innerHTML += + `

${payload.notification?.title || 'Notification'}: ${payload.notification?.body || ''}

`; + } +}); + document.addEventListener('DOMContentLoaded', () => { + // Request notification permission and get token right away + requestNotificationPermissionAndToken(); + const bTextOnlyInference = document.getElementById('bTextOnlyInference') as HTMLButtonElement; const bTextAndImageInference = document.getElementById('bTextAndImageInference') as HTMLButtonElement;