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!
Related
In my Nextjs project I'm trying to implement push notification with firebase messaging (my firebase version is 8.10.0), after creating the firebase-messaging-sw.js file in my public folder:
importScripts(
"https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js"
);
importScripts(
"https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js"
);
const firebaseConfig = {
apiKey: "***",
authDomain: "***",
projectId: "***",
storageBucket: "***",
messagingSenderId: "***",
appId: "***",
measurementId: "***"
};
firebase.initializeApp(firebaseConfig)
const messaging = firebase.messaging();
messaging.onBackgroundMessage((payload) => {
const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: null,
};
self.registration.showNotification(notificationTitle, notificationOptions);
});
I now created a [utility] file (that I named Firebase.js) where I'll implement helper functions like the request token function.
Here is a code snippet from that file:
import firebase from "firebase/app";
import "firebase/messaging";
const firebaseConfig = {
apiKey: "***",
authDomain: "***",
projectId: "***",
storageBucket: "***",
messagingSenderId: "***",
appId: "***",
measurementId: "***"
};
!firebase.apps.length && firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
export const requestForToken = () => {
// func that generates and returns a FCM token
};
export const onMessageListener = async () =>
new Promise((resolve) => {
messaging.onMessage((payload) => {
resolve(payload);
}
);
});
Now to use those functions I created another file Notification.js:
import React, { useState, useEffect } from "react";
import { toast } from "react-toastify";
import { requestForToken, onMessageListener } from "./Firebase";
const Notification = () => {
const [notification, setNotification] = useState({ title: "", body: "" });
useEffect(() => {
requestForToken();
}, []);
const ToastDisplay = () => {
return (
<>
<b>{notification?.title} </b>
<p>{notification?.body}</p>
</>
);
};
const notify = () => toast(<ToastDisplay />);
useEffect(() => {
notification?.title && notify();
}, [notification]);
onMessageListener()
.then((payload) => {
setNotification({
title: payload?.notification?.title,
body: payload?.notification?.body,
});
})
.catch((err) => console.log("failed: ", err));
return <></>;
};
export default Notification;
I imported Notification.js in _app.js and when I run my app I get the following error:
And I can't understand the reason why and [more importantly] how to fix it.
Hope this should work as All the setup I have worked inclined with your requirement,
Here are version's those I am using,
"next": "^12.0.7",
"firebase": "^8.6.8",
"#firebase/installations": "^0.5.4"
Here is firebase init'n,
/* eslint-disable import/prefer-default-export */
// import firebase from 'firebase/app';
import firebaseClient from "firebase/app";
import "firebase/installations";
import "firebase/auth";
import "firebase/messaging";
import "firebase/functions";
import "firebase/analytics";
const CLIENT_CONFIG = {
apiKey: "***",
authDomain: "***",
databaseURL: "***",
projectId: "***",
storageBucket: "***",
messagingSenderId: "***",
appId: "***",
measurementId: "***",
};
if (typeof window !== "undefined" && firebaseClient.apps?.length <= 0) {
firebaseClient.initializeApp(CLIENT_CONFIG);
(window as any).firebase = firebaseClient;
if (firebaseClient.messaging.isSupported()) {
const msg = firebaseClient.messaging();
const creds = {
vapidKey: process.env.NEXT_PUBLIC_FIREBASE_WEB_FCM_TOKEN
? process.env.NEXT_PUBLIC_FIREBASE_WEB_FCM_TOKEN
: "",
};
msg.getToken(
creds,
)
.then((token) => {
// Send the token to your app server if notification service granted
console.log(token);
})
.catch((err) => {
// If user blocks notification service
console.log(err);
});
}
}
export { firebaseClient };
Here is the firebase-messaging-sw.js at public folder
/* eslint-disable space-before-function-paren */
if ("serviceWorker" in navigator) {
navigator.serviceWorker
.register("../firebase-messaging-sw.js")
.then((registration) => {
console.log("Registration successful, scope is:", registration.scope);
})
.catch((err) => {
console.log("Service worker registration failed, error:", err);
});
}
Hope this get your working!.
Try this:
import { initializeApp } from "firebase/app";
import { getMessaging, onMessage } from "firebase/messaging";
const firebaseConfig = {
// ...
};
const app = initializeApp(firebaseConfig);
const messaging = getMessaging(app);
onMessage(messaging, (payload) => {
console.log('Message received. ', payload);
// ...
})
// ...
Also take a look into firebase docs
EDIT:
Take a look here too. It's showing how to receive messages into client.
Hope I've helped you with something :)
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);
trying to send push notification to app but i need permission from user for that but getting this error that messaging.requestPermission is not a function ,
here is my code for push notification.js file
import * as firebase from 'firebase/app';
import { getMessaging } from "firebase/messaging";
export const initializeFirebase = () => {
firebase.initializeApp({
apiKey: "",
authDomain: "",
projectId: "pushnotification-9b180",
storageBucket: "pushnotification-9b180.appspot.com",
messagingSenderId: "878043563283",
appId: "1:878043563283:web:c2a44f3c8b02ad8a17c6e6",
measurementId: "G-GMWQKL94ZD"
});
}
export const askForPermissionToReceiveNotifications = async () => {
try {
const messaging = getMessaging();
await messaging.requestPermission();
const token = await messaging.getToken();
console.log('Your token is:', token);
return token;
} catch (error) {
console.error(error);
}
}
Here is the screenshot of errorserros
What are you using react-native or react?
but in react-native way you need add this line
import messaging from '#react-native-firebase/messaging';
you donĀ“t need
const messaging = getMessaging();
import * as firebase from 'firebase/app';
import { getMessaging } from "firebase/messaging";
export const initializeFirebase = () => {
firebase.initializeApp({
apiKey: "",
authDomain: "",
projectId: "pushnotification-9b180",
storageBucket: "pushnotification-9b180.appspot.com",
messagingSenderId: "878043563283",
appId: "1:878043563283:web:c2a44f3c8b02ad8a17c6e6",
measurementId: "G-GMWQKL94ZD"
});
}
export const askForPermissionToReceiveNotifications = async () => {
try {
const messaging = getMessaging();
await messaging.requestPermission();
const token = await messaging.getToken();
console.log('Your token is:', token);
return token;
} catch (error) {
console.error(error);
}
}
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);
});
}
});
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