N
Novu5mo ago
harrisyn

Firebase Push Notification

Hi, I have enabled firebase for push notifications, however I am confused about how to make the notifications clickable to an external link. I have seen the documentation example that uses a relative link, am I correct to assume that that relative link is added to the source of the notification or where the device token was generated? Also, how do I replace that with a complete url?
50 Replies
empe
empe5mo ago
Hey @harrisyn! Sorry I don't quite understand your question, can you please elaborate? Maybe provide a code snippet of the request you are making
empe
empe5mo ago
Novu
How to send PUSH notifications to iOS devices with FCM using Novu -...
Learn how to integrate Firebase Cloud Messaging with Novu and send notifications to iOS
empe
empe5mo ago
Hope it would help a bit Hey @harrisyn, did it help?
harrisyn
harrisyn5mo ago
Hi, just got back online, I will take a look. thanks @Emil
harrisyn
harrisyn5mo ago
Actually that wasn't what I was after. I am receiving this push notification, and it doesn't contain the icon I set as part of the payload, nor does is it clickable to the relative link. I have followed the example in the documentation and still get no joy
import { Novu } from "@novu/node";

const novu = new Novu("<NOVU_API_KEY>");

novu.trigger("<WORKFLOW_TRIGGER_IDENTIFIER>", {
to: {
subscriberId: "<SUBSCRIBER_ID>",
},
payload: {
abc: "def", // If the notification is a data notification, the payload will be sent as the data
},
overrides: {
fcm: {
// type: 'data' => will turn this into an FCM data notification, where the payload is sent as a data notification. If the type is not set, you can use the "data" override to send notification messages with optional data payload
type: "data",

// URL of an image to be displayed in the notification.
imageUrl: "https://domain.com/image.png",

// If type is not set, you can use the "data" override to send notification messages with optional data payload
data: {
key: "value",
},

// Check FCM Overrides section above for these types
android: {},
apns: {},
webPush: {},
fcmOptions: {},
},
},
});
import { Novu } from "@novu/node";

const novu = new Novu("<NOVU_API_KEY>");

novu.trigger("<WORKFLOW_TRIGGER_IDENTIFIER>", {
to: {
subscriberId: "<SUBSCRIBER_ID>",
},
payload: {
abc: "def", // If the notification is a data notification, the payload will be sent as the data
},
overrides: {
fcm: {
// type: 'data' => will turn this into an FCM data notification, where the payload is sent as a data notification. If the type is not set, you can use the "data" override to send notification messages with optional data payload
type: "data",

// URL of an image to be displayed in the notification.
imageUrl: "https://domain.com/image.png",

// If type is not set, you can use the "data" override to send notification messages with optional data payload
data: {
key: "value",
},

// Check FCM Overrides section above for these types
android: {},
apns: {},
webPush: {},
fcmOptions: {},
},
},
});
and for relative links
import { Novu } from "@novu/node";

const novu = new Novu("<NOVU_API_KEY>");

novu.trigger("<WORKFLOW_TRIGGER_IDENTIFIER>", {
to: {
subscriberId: "<SUBSCRIBER_ID>",
},
payload: {
abc: "def", // If the notification is a data notification, the payload will be sent as the data
},
overrides: {
fcm: {
webPush: {
fcmOptions: {
link: "/foo",
},
},
},
},
});
import { Novu } from "@novu/node";

const novu = new Novu("<NOVU_API_KEY>");

novu.trigger("<WORKFLOW_TRIGGER_IDENTIFIER>", {
to: {
subscriberId: "<SUBSCRIBER_ID>",
},
payload: {
abc: "def", // If the notification is a data notification, the payload will be sent as the data
},
overrides: {
fcm: {
webPush: {
fcmOptions: {
link: "/foo",
},
},
},
},
});
the link doesn't seem to work, is there something I have missed?
No description
empe
empe5mo ago
Do I understand correctly that you are trying to configure Web push notifications? Because if so, the guide that I've sent really will be little to no help.
empe
empe5mo ago
To begin troubleshooting, could you please provide any relevant screenshots and additional code snippets? To ensure we're on the same page, here are some essential points you may have overlooked: 1. Follow the official Firebase guide on setting up a JavaScript Firebase Cloud Messaging client app here. 2. Verify that you've correctly configured the FCM provider at Novu as outlined in their documentation. 3. Confirm that you've integrated Novu into your backend system. 4. Make sure you've created a subscriber in Novu and associated their credentials with the appropriate device tokens. 5. Install Firebase in your project using 'npm install firebase,' initialize Firebase with your configuration, and generate tokens using the 'getToken' method after obtaining user permission for frontend integration. 6. Ensure the presence of a service worker file named firebase-messaging-sw.js for Firebase's background listener service.
Novu
Start Point - Novu
Novu is an open-source notification infrastructure, built for engineering teams to help them build rich product notification experiences.
harrisyn
harrisyn5mo ago
thanks for the feedback @Emil yes, I am setting up web push notifications. I have setup Novu, FCM and configured a service worker, so at the moment I receive the push notifications. My challenge is on the payload and how the push notification appears on my system. Most especially around displaying the push notification icon (doesn't show despite including it as an override in the novu payload), and the push notification does not respond to clicks (the link included in the webpush override doesn't seem to work)
empe
empe5mo ago
Can we try calling a URL link instead of a relative link? Also, let's make few other attempts, and please tell me it any of them worked, Regarding the issue with the push notification icon not displaying, ensure that you have correctly set the icon in the webPush configuration under overrides when sending the notification. For web push notifications, the icon can be specified using the icon property within the notification object of webPush overrides:
"overrides": {
"fcm": {
"webPush": {
"notification": {
"icon": "https://example.com/path-to-icon/icon.png"
}
}
}
}
"overrides": {
"fcm": {
"webPush": {
"notification": {
"icon": "https://example.com/path-to-icon/icon.png"
}
}
}
}
To address the issue of the push notification not responding to clicks, ensure that you are using the link property with a relative URL within the fcmOptions of the webPush configuration. This will allow users to be directed to the specified relative path on your website upon clicking the notification:
"overrides": {
"fcm": {
"webPush": {
"fcmOptions": {
"link": "/path-on-your-site"
}
}
}
}
"overrides": {
"fcm": {
"webPush": {
"fcmOptions": {
"link": "/path-on-your-site"
}
}
}
}
Make sure that the service worker is properly configured to handle the click event on the notification. If the notification includes a data object with the link, the service worker may use that link for navigation when the notification is clicked. The service worker code should resemble this:
self.addEventListener('notificationclick', function(event) {
// Assuming 'link' is passed inside the notification 'data'
const link = event.notification.data.link;
event.notification.close(); // Close the notification
// Open the link
event.waitUntil(
clients.openWindow(link)
);
});
self.addEventListener('notificationclick', function(event) {
// Assuming 'link' is passed inside the notification 'data'
const link = event.notification.data.link;
event.notification.close(); // Close the notification
// Open the link
event.waitUntil(
clients.openWindow(link)
);
});
I found that the following resources could be helpful: https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#webpushconfig https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages#webpushfcmoptions https://github.com/firebase/quickstart-js/tree/master/messaging Hope we will have a breakthrough today 🙂
harrisyn
harrisyn5mo ago
Hi @Emil I have spent some time trying to debug this. What I have concluded is that the overrides section doesn't work for me.
overrides: {
fcm: {
// imageUrl: config.qshopLogo,
// type: "data",
data: {
link: `/admin/orders/${order._id}`,
fullUrl: `${process.env.PUBLIC_URL}/admin/orders/${order._id}`
},
webPush: {
notification: {
icon: config.qshopLogo,
link: `/admin/orders/${order._id}`
},
fcmOptions: {
link: `/admin/orders/${order._id}`
},
}
}
}
overrides: {
fcm: {
// imageUrl: config.qshopLogo,
// type: "data",
data: {
link: `/admin/orders/${order._id}`,
fullUrl: `${process.env.PUBLIC_URL}/admin/orders/${order._id}`
},
webPush: {
notification: {
icon: config.qshopLogo,
link: `/admin/orders/${order._id}`
},
fcmOptions: {
link: `/admin/orders/${order._id}`
},
}
}
}
I have tried all these options, and I can only received on the client side, the title, body and data. I had hoped using type: "data" will mean that the payload will be shown in my console, but when I set that, I only receive title and body and data is null, so not being able to replace the notification property also means that I get double notifications So in effect, when I test sending messages to FCM, my application works correctly and displays the right notification (since I send a data object instead of a notification object). Using the Novu trigger however simply sends the notification property all the time, the novu guide suggests that the "type : 'data'" should remove the notification property, this seems to also be in the codebase in the file novu/providers/fcm/src/lib/fcm.provider.ts
if (type === 'data') {
res = await this.messaging.sendMulticast({
tokens: options.target,
data: {
...payload,
title: options.title,
body: options.content,
message: options.content,
},
android,
apns,
fcmOptions,
webpush,
});
} else {
res = await this.messaging.sendMulticast({
tokens: options.target,
notification: {
title: options.title,
body: options.content,
...overridesData,
},
data,
android,
apns,
fcmOptions,
webpush,
});
}
if (type === 'data') {
res = await this.messaging.sendMulticast({
tokens: options.target,
data: {
...payload,
title: options.title,
body: options.content,
message: options.content,
},
android,
apns,
fcmOptions,
webpush,
});
} else {
res = await this.messaging.sendMulticast({
tokens: options.target,
notification: {
title: options.title,
body: options.content,
...overridesData,
},
data,
android,
apns,
fcmOptions,
webpush,
});
}
this seems to be doing exactly that, but I am not sure it is either receiving the overrides or the documentation relating to how it is triggered is incorrect. The other option I tried, since FCM will trigger a notification automatically when the payload includes a notification property, was to disable the the additional trigger, the default notification would have been ok, if I can include an icon and a badge, the imageUrl works but it is producing a larger background banner to the notification.
empe
empe5mo ago
I've requested some help from another team member, we are looking into it..
Paweł T.
Paweł T.5mo ago
hey @harrisyn! 👋 not sure where you are with your issues, but I've tested this and it works for me with this code:
overrides": {
"fcm": {
"data": { "asdf2": "asdf2 ", "url": "https://epicreact.dev" },
"imageUrl": "http://localhost:3001/logo192.png"
}
}
overrides": {
"fcm": {
"data": { "asdf2": "asdf2 ", "url": "https://epicreact.dev" },
"imageUrl": "http://localhost:3001/logo192.png"
}
}
on the service worker side you should have code like this:
messaging.onBackgroundMessage(function(payload) {
console.log('Received background message ', payload);

const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: payload.notification.image,
data: {
url: payload.data.url
}
};

self.registration.showNotification(notificationTitle,
notificationOptions);
});

self.addEventListener('notificationclick', function(event) {
event.notification.close();
console.log('Received notificationclick event ', event);
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
})
messaging.onBackgroundMessage(function(payload) {
console.log('Received background message ', payload);

const notificationTitle = payload.notification.title;
const notificationOptions = {
body: payload.notification.body,
icon: payload.notification.image,
data: {
url: payload.data.url
}
};

self.registration.showNotification(notificationTitle,
notificationOptions);
});

self.addEventListener('notificationclick', function(event) {
event.notification.close();
console.log('Received notificationclick event ', event);
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
})
From what I see the overrides.fcm.imageUrl becomes payload.notification.image and overrides.fcm.data becomes payload.data. I hope that it helps to you 😉
harrisyn
harrisyn5mo ago
@Paweł T. thanks for looking at this.
overrides": {
"fcm": {
"data": { "asdf2": "asdf2 ", "url": "https://epicreact.dev" },
"imageUrl": "http://localhost:3001/logo192.png"
}
}
overrides": {
"fcm": {
"data": { "asdf2": "asdf2 ", "url": "https://epicreact.dev" },
"imageUrl": "http://localhost:3001/logo192.png"
}
}
I tested a variant of this, and if you look at my submitted code snippet, it is similar, the data is present in the payload, but so is notification, so I end up with two push notifications, the system default and the one from the worker.
{"data":{"link":"/admin/orders/65b104d3b9f40137c2de4d52"},"from":"638004111100","priority":"normal","notification":{"title":"You Have A New Order","body":"Order #2563-688868-1233, Order status: Pending Payment"},"fcmMessageId":"41234f34-3e7b-4983-9418-633d7327c1fa"}
{"data":{"link":"/admin/orders/65b104d3b9f40137c2de4d52"},"from":"638004111100","priority":"normal","notification":{"title":"You Have A New Order","body":"Order #2563-688868-1233, Order status: Pending Payment"},"fcmMessageId":"41234f34-3e7b-4983-9418-633d7327c1fa"}
this is what I received when I include data. The aim is to completely replace/remove notification from what is sent by Novu.
Paweł T.
Paweł T.5mo ago
Ok, got it. When you set the "type": "data" then the message will be sent as a "data notification" meaning the payload will be included in the data property of the message, as well as other fields like title, body. Can you please try this:
"payload": {
"url": "https://epicreact.dev", "image": "http://localhost:3001/logo192.png"
},
"overrides": {
"fcm": {
"type": "data"
}
}
"payload": {
"url": "https://epicreact.dev", "image": "http://localhost:3001/logo192.png"
},
"overrides": {
"fcm": {
"type": "data"
}
}
and then the worker should be like:
messaging.onBackgroundMessage(function(payload) {
console.log('Received background message ', payload);

const notificationTitle = payload.data.title;
const notificationOptions = {
body: payload.data.body,
icon: payload.data.image,
data: {
url: payload.data.url
}
};

self.registration.showNotification(notificationTitle,
notificationOptions);
});

self.addEventListener('notificationclick', function(event) {
event.notification.close();
console.log('Received notificationclick event ', event);
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
})
messaging.onBackgroundMessage(function(payload) {
console.log('Received background message ', payload);

const notificationTitle = payload.data.title;
const notificationOptions = {
body: payload.data.body,
icon: payload.data.image,
data: {
url: payload.data.url
}
};

self.registration.showNotification(notificationTitle,
notificationOptions);
});

self.addEventListener('notificationclick', function(event) {
event.notification.close();
console.log('Received notificationclick event ', event);
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
})
Paweł T.
Paweł T.5mo ago
No description
harrisyn
harrisyn5mo ago
Tried that as well the type : data didn't replace the notification is it possible that that is being controlled by a different config? when I send it directly, to FCM, it works as expected, but as a workflow triggered by novu, it doesn't work
Novu_Bot
Novu_Bot5mo ago
@harrisyn, you just advanced to level 7!
Paweł T.
Paweł T.5mo ago
I'm not sure what you are saying but in the above image I don't receive the notification property and that code works well.
harrisyn
harrisyn5mo ago
I tried,
overrides: {
fcm: {
type: "data",
}
}
overrides: {
fcm: {
type: "data",
}
}
and it didn't work, I received
{"from":"638004111100","priority":"normal","notification":{"title":"Subscription Activated","body":"Your subscription for the plan has been activated."},"fcmMessageId":"12ac7521-4748-4a32-aff9-6b5db0a41cee"}
{"from":"638004111100","priority":"normal","notification":{"title":"Subscription Activated","body":"Your subscription for the plan has been activated."},"fcmMessageId":"12ac7521-4748-4a32-aff9-6b5db0a41cee"}
just to be sure, I also tried with quotes around the object properties as in your example and still had the same result. the fact that it works as expected for you, may limit the issue to something about my setup, although I have absolutely no idea why that is the case
Paweł T.
Paweł T.5mo ago
Interesting 🤔 I'm not sure what might be wrong, but when the overrides.fcm.type = "data" then it should not send the notification field from what I see in the code. I'm not sure how it's possible that you still see it. Have you tried to generate a new token? and update the subscriber with it?
harrisyn
harrisyn5mo ago
I went through the code as well, so I saw that it was supposed to work that way, but I have tried every possible variant in that trigger payload but never got the same result. Also the webPush override never worked as well, the only change I can make that shows up in the payload is the imageUrl and data (although this still adds the notification property) Yup, testing on 3 different laptops
Paweł T.
Paweł T.5mo ago
I don't know what I can suggest here, I created the app a couple of minutes ago and with that configuration, it works for me.
harrisyn
harrisyn5mo ago
cleared page storage etc, also tracking the push notifications
No description
harrisyn
harrisyn5mo ago
to see what was received where in the api do you suppose I can debug this? I am happy to go into the shell and put in console.logs to see where it gets missing if I need to
Paweł T.
Paweł T.5mo ago
If you mean by running the Novu locally then the code that you mentioned here is the right place: https://discord.com/channels/895029566685462578/1197599228336287874/1199713354802020372
harrisyn
harrisyn5mo ago
I am running the docker containers so not sure where in the api (I supposed it is in there) that file is.
Paweł T.
Paweł T.5mo ago
you have to look over the node_modules/@novu/fcm in the container also, it works for me well on the Novu Cloud (prod) 🤷‍♂️
harrisyn
harrisyn5mo ago
😭
harrisyn
harrisyn5mo ago
Sent
{
"name": "subscription-activation",
"to": {
"subscriberId": "62ea6482a0647c5d76e30d22",
"email": "qfashions@qshop.com"
},
"payload": {
"shop": {
"name": "Qfashions"
},
"subscription": {
"recurringPayment": "No"
},
"format": "2124-01-24",
"subscriber": {
"firstName": "Tarebi"
},
"process": {
"env": {
"CONTACT_EMAIL": "hello@qshop.ng"
}
},
"plan": {
"name": "Starter"
}
},
"overrides": {
"fcm": {
"type": "data"
}
}
}
{
"name": "subscription-activation",
"to": {
"subscriberId": "62ea6482a0647c5d76e30d22",
"email": "qfashions@qshop.com"
},
"payload": {
"shop": {
"name": "Qfashions"
},
"subscription": {
"recurringPayment": "No"
},
"format": "2124-01-24",
"subscriber": {
"firstName": "Tarebi"
},
"process": {
"env": {
"CONTACT_EMAIL": "hello@qshop.ng"
}
},
"plan": {
"name": "Starter"
}
},
"overrides": {
"fcm": {
"type": "data"
}
}
}
Received
No description
Paweł T.
Paweł T.5mo ago
Which version of docker images are you using?
harrisyn
harrisyn5mo ago
0.22.0
harrisyn
harrisyn5mo ago
No description
Paweł T.
Paweł T.5mo ago
Maybe its about firebase sdk, because I was using 9
harrisyn
harrisyn5mo ago
it's same for me
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-messaging-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/9.0.0/firebase-messaging-compat.js');
Paweł T.
Paweł T.5mo ago
😔
harrisyn
harrisyn5mo ago
this is why it is even more confusing.
{
"name": "subscription-activation",
"to": {
"subscriberId": "62ea6482a0647c5d76e30d22",
"email": "qfashions@qshop.com"
},
"payload": {
"shop": {
"name": "Qfashions"
},
"subscription": {
"recurringPayment": "No"
},
"format": "2124-01-24",
"subscriber": {
"firstName": "Tarebi"
},
"process": {
"env": {
"CONTACT_EMAIL": "hello@qshop.ng"
}
},
"plan": {
"name": "Starter"
}
},
"overrides": {
"fcm": {
"type": "data",
"data" : {
"sample" : "sample"
}
}
}
}
{
"name": "subscription-activation",
"to": {
"subscriberId": "62ea6482a0647c5d76e30d22",
"email": "qfashions@qshop.com"
},
"payload": {
"shop": {
"name": "Qfashions"
},
"subscription": {
"recurringPayment": "No"
},
"format": "2124-01-24",
"subscriber": {
"firstName": "Tarebi"
},
"process": {
"env": {
"CONTACT_EMAIL": "hello@qshop.ng"
}
},
"plan": {
"name": "Starter"
}
},
"overrides": {
"fcm": {
"type": "data",
"data" : {
"sample" : "sample"
}
}
}
}
when I include data ( i know it will overwrite the type)
No description
harrisyn
harrisyn5mo ago
anything else aside data and imageUrl, will not show up in the final received notification
Paweł T.
Paweł T.5mo ago
And you dont accidentially running another docker container with an older version?
harrisyn
harrisyn5mo ago
nope just shut down the containers and done a docker compose pull then up again, also verified that my novu instance was down during that process, yep, definitely the same containers might be an issue with the images unless you are running the images locally as well by the way, I did an exec into the api container and couldn't locate the file wanted to look if the contents were the same
Paweł T.
Paweł T.5mo ago
you have to exec into the worker container that is the one that is sending the messages... look over this path node_modules/@novu/application-generic/node_modules/@novu/fcm/build/module/lib and the file will be called fcm.provider.js
harrisyn
harrisyn5mo ago
got it, checking now
harrisyn
harrisyn5mo ago
it is different
harrisyn
harrisyn5mo ago
Definitely looking like an image build issue now
Paweł T.
Paweł T.5mo ago
can you try with the latest image then?
harrisyn
harrisyn5mo ago
I am using the latest image unless there is one after 0.22.0
Paweł T.
Paweł T.5mo ago
I mean with the tag latest
harrisyn
harrisyn5mo ago
ok yup, updated contents in this one will test and feedback
harrisyn
harrisyn5mo ago
thanks @Emil and @Paweł T. works as expected now The challenge was the 0.22.0 image
No description
empe
empe5mo ago
WOWOWOWOW Finaly a breakthrough!!!! Thank you for the update @harrisyn! Glad you manage at the end! Where do you think we should add it in the docs for other users?
harrisyn
harrisyn5mo ago
I think the docs is fine as is, it's the tagged images that should be checked. I think the FCM docs can be expanded to include the relevance of the type property and how it can be used to avoid duplicate notifications, also the notificationClick handler will improve the docs as well.