Firebase Cloud Messaging works from localhost but not on Github Pages - javascript

**Edit: This is definitely a Github Pages issue. I deployed to Firebase Hosting and everything works as it should.
Here's my js to get the token. It is fully functional when running from localhost.
const messaging = firebase.messaging();
messaging.requestPermission()
.then(function () {
console.log('have permission');
return messaging.getToken();
console.log(messaging.getToken());
})
.then(function (token) {
newToken = token
console.log(newToken);
})
.catch(function (err) {
console.log(err);
})
messaging.onMessage(function (payload) {
console.log('onMessage: ', payload)
})
Here's is what is in my firebase-messaging-sw.js file:
importScripts("https://www.gstatic.com/firebasejs/5.2.0/firebase-app.js")
importScripts("https://www.gstatic.com/firebasejs/5.2.0/firebase-messaging.js")
var config = {
apiKey: "...",
authDomain: "...",
databaseURL: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "..."
};
firebase.initializeApp(config);
// const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function (payload) {
const title = 'hello world';
const options = {
body: payload.data.status
}
return self.registration.showNotification(title, options)
})
I get the following error when I try to use it from Github Pages:
Failed to register/update a ServiceWorker for scope
‘https://adambeck7.github.io/firebase-cloud-messaging-push-scope’:
Load failed with status 404 for script
‘https://adambeck7.github.io/firebase-messaging-sw.js’

Related

Next Js cant find Service messaging (firebase-cloud-messaging)

Hi I using firebase cloud messaging in next js project and when I try to run or build my project I get this error :
info - Checking validity of types
info - Creating an optimized production build
info - Compiled successfully
info - Collecting page data ...node:internal/process/promises:246
triggerUncaughtException(err, true /* fromPromise */);
^
Error: Service messaging is not available
at Provider.getImmediate (file:///I:/Work/Web/Php/Project/wamp/www/test/node_modules/#firebase/component/dist/esm/index.esm2017.js:147:23)
at getMessagingInWindow (I:\Work\Web\Php\Project\wamp\www\test\node_modules#firebase\messaging\dist\index.cjs.js:1460:74)
at I:\Work\Web\Php\Project\wamp\www\test.next\server\pages_app.js:117:83 {
type: 'Error'
}
my code :
it seems this problem happens because using getMessaging
firbase.js
import { initializeApp } from 'firebase/app';
import { getMessaging, getToken, onMessage } from "firebase/messaging";
var firebaseConfig = {
apiKey: "----",
authDomain: "---",
projectId: "---",
storageBucket: "---",
messagingSenderId: "---",
appId: "---",
measurementId: "---"
};
const firebaseApp = initializeApp(firebaseConfig);
const messaging = getMessaging(firebaseApp);
export const fetchToken = (setTokenFound) => {
return getToken(messaging, {vapidKey: '---'}).then((currentToken) => {
if (currentToken) {
console.log('current token for client: ', currentToken);
setTokenFound(true);
// Track the token -> client mapping, by sending to backend server
// show on the UI that permission is secured
} else {
console.log('No registration token available. Request permission to generate one.');
setTokenFound(false);
// shows on the UI that permission is required
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
// catch error while creating client token
});
}
export const onMessageListener = () =>
new Promise((resolve) => {
onMessage(messaging, (payload) => {
resolve(payload);
});
});
firebase-messaging-sw.js
// Scripts for firebase and firebase messaging
importScripts('https://www.gstatic.com/firebasejs/9.6.11/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.6.11/firebase-messaging-compat.js');
// Initialize the Firebase app in the service worker by passing the generated config
const firebaseConfig = {
apiKey: "----",
authDomain: "---",
projectId: "---",
storageBucket: "---",
messagingSenderId: "---",
appId: "---",
measurementId: "---"
};
firebase.initializeApp(firebaseConfig);
// Retrieve firebase messaging
const messaging = firebase.messaging();
messaging.onBackgroundMessage(function(payload) {
console.log('Received background message ', payload);
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
};
self.registration.showNotification(notificationTitle,
notificationOptions);
});
_app.tsx
import {fetchToken,onMessageListener} from '../tools/firebase'
const [notification, setNotification] = useState({title: '', body: ''});
const [isTokenFound, setTokenFound] = useState(false);
useEffect(() => {
fetchToken(setTokenFound)
onMessageListener().then(payload => {
setNotification({title: payload.notification.title, body: payload.notification.body})
console.log(payload);
}).catch(err => console.log('failed: ', err));
}, []);
i had same issue turns out it was firebase v9 issue
using firebase v8 worked for me
npm i firebase#8.2.3
after installing v8 don't forget to change syntax its firebase.initializeApp(firebaseConfig);

Unable to change notification title in Firebase Cloud Messaging

I am now able to implement push notifications with Firebase Cloud Messaging, and the push notifications themselves are delivered, but I am having trouble changing their content.
The default title is "This site has been updated in the background", but I changed it to any text.
Environment
Vue CLI
TypeScript
main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './registerServiceWorker'
import firebase from 'firebase/compat/app';
import { getMessaging, getToken } from "firebase/messaging";
const firebaseConfig = {
apiKey: "xxx",
authDomain: "xxx",
projectId: "xxx",
storageBucket: "xxx",
messagingSenderId: "xxx",
appId: "xxx",
measurementId: "xxx"
};
const firebaseApp = firebase.initializeApp(firebaseConfig);
const app = createApp(App)
installElementPlus(app)
app
.use(store)
.use(router)
.component('MqResponsive', Vue3Mq.MqResponsive)
.mount('#app')
const messaging = getMessaging(firebaseApp);
const vapidKey = {
vapidKey:
"xxx",
};
// Messaging
getToken(messaging, { vapidKey: 'xxx' }).then((currentToken) => {
if (currentToken) {
// Send the token to your server and update the UI if necessary
console.log("currentToken : ", currentToken);
// ...
} else {
// Show permission request UI
console.log('No registration token available. Request permission to generate one.');
// ...
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
// ...
});
firebase-messaging-sw.js
import firebase from 'firebase/compat/app';
import { onBackgroundMessage } from "firebase/messaging/sw";
import { getMessaging, getToken, onMessage } from "firebase/messaging";
const firebaseConfig = {
apiKey: "xxx",
authDomain: "xxx",
projectId: "xxx",
storageBucket: "xxx",
messagingSenderId: "xxx",
appId: "xxx",
measurementId: "xxx"
};
const firebaseApp = firebase.initializeApp(firebaseConfig);
const messaging = getMessaging(firebaseApp);
const vapidKey = {
vapidKey:
"xxx",
};
// Messaging
getToken(messaging, { vapidKey: 'xxx' }).then((currentToken) => {
if (currentToken) {
// Send the token to your server and update the UI if necessary
console.log("currentToken : ", currentToken);
// ...
} else {
// Show permission request UI
console.log('No registration token available. Request permission to generate one.');
// ...
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
// ...
});
onMessage(messaging, (payload) => {
console.log('Message received. ', payload);
// ...
});
onBackgroundMessage(messaging, (payload) => {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
self.addEventListener('push', async function (event) {
event.waitUntil(
self.registration.showNotification('title', {
body: 'body'
})
);
});
});
The image is localhost, but deploying to the web did not change the result.
I also tested on Firebase Messaging and downloaded as a PWA and again the results did not change.
What is the problem??
Thank you in advance!

How to integrate PWA with Next.js to allow for notifications and push notifications

I'm building a PWA with next.js and have been having a few issues.
I am trying to integrate in device motion to my users accounts and geolocation, and then notifications.
Basing this off of this repo, https://github.com/shadowwalker/next-pwa/ , and this tutorial, https://medium.com/#sarafathulla/how-to-add-firebase-push-notifications-in-next-js-react-8eecc56b5cab .
As well as these API's, https://whatwebcando.today/device-motion.html and https://whatwebcando.today/geolocation.html .
Currently the PWA is boilerplate using next-pwa,
next.config.js
module.exports = withPWA({
pwa: {
disable: process.env.NODE_ENV === 'development',
dest: 'public',
runtimeCaching,
},
poweredByHeader: false,
},
withBundleAnalyzer(),
)
I am very confused about how one can integrate just the simple device motion into the PWA, and how to move forward in general.
If someone could point me in the right direction that would be brilliant! So different from usual web dev code.
this working for me
// public/firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/7.9.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.9.1/firebase-messaging.js');
firebase.initializeApp({
apiKey: '****',
authDomain: '*****',
projectId: '*****',
storageBucket: '******',
messagingSenderId: '*****',
appId: '*****',
measurementId: '*****',
});
firebase.messaging();
//background notifications will be received here
firebase.messaging().setBackgroundMessageHandler((payload) => {
const { title, body } = JSON.parse(payload.data.notification);
var options = {
body,
icon: '/icons/launcher-icon-4x.png',
};
registration.showNotification(title, options);
});
// webpush.js
import 'firebase/messaging';
import firebase from 'firebase/app';
import localforage from 'localforage';
const firebaseCloudMessaging = {
//checking whether token is available in indexed DB
tokenInlocalforage: async () => {
return localforage.getItem('fcm_token');
},
//initializing firebase app
init: async function () {
if (!firebase.apps.length) {
firebase.initializeApp({
apiKey: '****',
authDomain: '*****',
projectId: '*******',
storageBucket: '******',
messagingSenderId: '******',
appId: '*****',
measurementId: '*******',
});
try {
const messaging = firebase.messaging();
const tokenInLocalForage = await this.tokenInlocalforage();
//if FCM token is already there just return the token
if (tokenInLocalForage !== null) {
return tokenInLocalForage;
}
//requesting notification permission from browser
const status = await Notification.requestPermission();
if (status && status === 'granted') {
//getting token from FCM
const fcm_token = await messaging.getToken();
if (fcm_token) {
//setting FCM token in indexed db using localforage
localforage.setItem('fcm_token', fcm_token);
//return the FCM token after saving it
return fcm_token;
}
}
} catch (error) {
console.error(error);
return null;
}
}
},
};
export { firebaseCloudMessaging };
// _app.js
import { firebaseCloudMessaging } from '../webPush';
import firebase from 'firebase/app';
useEffect(() => {
setToken();
async function setToken() {
try {
const token = await firebaseCloudMessaging.init();
if (token) {
getMessage();
}
} catch (error) {
console.log(error);
}
}
function getMessage() {
const messaging = firebase.messaging();
console.log({ messaging });
messaging.onMessage((message) => {
const { title, body } = JSON.parse(message.data.notification);
var options = {
body,
};
self.registration.showNotification(title, options);
});
}
});

PWA foreground push notifications

i have a problem with foreground push notifications.
I just want to get the data in the console for the moment but it didn't work. I follow the guide on firebase documentation but this function is never triggered...
messaging.onMessage((payload) => {
console.log('Message received. ', payload);
});
Background notifications works as expected.
Here is my VueJs file
import * as firebase from "firebase/app";
import 'firebase/messaging';
const config = {
apiKey: "",
authDomain: "",
databaseURL: "",
projectId: "",
storageBucket: "",
messagingSenderId: "",
appId: ""
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.usePublicVapidKey("");
export default {
name: 'App',
mounted() {
messaging.onMessage((payload) => { // Don't work here
console.log('Message received. ', payload);
});
this.getMsgPushToken();
},
methods: {
...mapMutations('auth', ['mutMsgPushToken']),
getMsgPushToken() {
let that = this
messaging.requestPermission().then(async function() {
messaging.getToken().then((token) => {
that.mutMsgPushToken(token); // Where i get the FCM token
})
}).catch((err) => {
console.log('Unable to get permission to notify.', err);
});
},
},
};
And my service worker
importScripts('https://www.gstatic.com/firebasejs/5.5.6/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/5.5.6/firebase-messaging.js');
firebase.initializeApp({
'messagingSenderId': ''
});
const messaging = firebase.messaging();
If you have any idea of what i'm missing, i would love to hear it ha ha

FCM WEB receive only data and hide notification section or Disable

I am trying to send data form my server to FCM, so that it can be shown on a specific section of my web page. It's like a stock application for example, where the data is constantly updated. In the same way am trying to achieve. So far I have configured it to receive data from FCM and it is being received. But the problem is that it shows the notification to like. My colleague are working on the same there is a option to send only data to the android app and hide notifications to be shown. Likewise I want to do it hear on web, but am unable to do it.
(function () {
// Initialize Firebase
var config = {
apiKey: "xxxxxxxxxxxxxx",
authDomain: "test-xxxxxxxx.xxxxxxxx.com",
databaseURL: "https://xxxxxx-xxxxxxxx.firebaseio.com",
projectId: "xxx-469e9",
storageBucket: "",
messagingSenderId: "xxxxxx"
};
firebase.initializeApp(config);
// Retrieve Firebase Messaging object.
const messaging = firebase.messaging();
messaging.requestPermission()
.then(function() {
console.log('Notification permission granted.');
return messaging.getToken();
})
.then(function(token) {
console.log(token);
})
.catch(function(err) {
console.log('Unable to get permission to notify.', err);
})
messaging.onMessage(function(payload) {
console.log("Message received. ", payload);
// ...
});
}());
on firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/4.3.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/4.3.1/firebase-messaging.js');
// Initialize Firebase
var config = {
apiKey: "xxxxxx",
authDomain: "xxxx-xxxxxxxxxx.com",
databaseURL: "https://xxx-xxx.firebaseio.com",
projectId: "xxxx-xxxxxxxxxx",
storageBucket: "",
messagingSenderId: "xxxxxxxxxxxx"
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
A hack would be to close the notification just after...
messaging.setBackgroundMessageHandler(function (payload) {
var realPush = true;
if(realPush)
{
const notificationOptions = {
body: "It is a REAL push",
data:"true"
};
//We display the notification
return self.registration.showNotification(title, notificationOptions);
}else
{
const notificationOptions = {
body: "It is a SILENT push",
data:"false"
};
//We display a fake notification
return self.registration.showNotification('To delete',notificationOptions).then(function () {
self.registration.getNotifications().then(notifications => {
console.log(notifications);
for (var i =0;i<notifications.length;i++)
{
if(notifications[i].data != "true")
{
//then we destroy the fake notification immedialtely !
notifications[i].close();
}
}
})
});
}
});
The realPush parameter is of course managed by yourself

Categories