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;