Flutter web app receives push notification but broswer doesn't show it - push-notification

I am being able to receive and display the notification on the console but it doesn't show up in the browser (chrome).
The steps I am following are:
I start the app and get notification token with the function
FirebaseMessaging.instance.getToken().then((String token) {
debugPrint('Token: $token');
});
The token from step 1. is inserted in the script below (the 'to' field) and the request is sent to Firebase servers
#!/bin/bash
DATA='{"notification": {"body": "This is a message","title": "Marcelo"}, "priority": "high", "data": {"click_action": "FLUTTER_NOTIFICATION_CLICK", "id": "1", "status": "done"}, "to": "eMkcLmwSSBeWXS_YEB-b_R:APA91bG2pyrDVr0BBoya0rQET0vfwTVE3aTeQsoqsxVMK70ypm6aaa-pNdX9uQ5BgEsoQGuVoe-EpeePJB8Q7XUfTvrTlgtRW8HSZ3qOaxotFUSaq8JqrgRtummIOnMFYUGqtg-sMP8Y"}'
curl https://fcm.googleapis.com/fcm/send -H "Content-Type:application/json" -X POST -d "$DATA" -H "Authorization: key=AAAAKavk7EY:APA91bEtq36uuNhvGSHu8hEE-EKNr3hsgso7IvDOWCHIZ6h_8LXPLz45EC3gxHUPxKxf3254TBM1bNxBby_8xP4U0pnsRh4JjV4uo4tbdBe2sSNrzZWoqTgcCTqmk3fIn3ltiJp3HKx2"
A success response is received back
{"multicast_id":5695802004264337317,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1615137996888514%2fd9afcdf9fd7ecd"}]}
The notification is received in the app in the form
FirebaseMessaging.onMessage.listen((RemoteMessage message)
{
RemoteNotification notification = message.notification;
if (notification != null) {
print('Title ${notification.title}');
print('Body ${notification.body}');
}
});
The browser however doesn't show the notification. What am I missing?

static onMessageWebNotification(NotificationData notificationData, String payloadData) {
html.window.navigator.serviceWorker.ready.then((registration) {
var notificationTitle = notificationData.title;
var notificationOptions = {
'body': notificationData.body,
'data': notificationData
};
registration.showNotification(
notificationTitle,
notificationOptions,
);
});
}

Related

Axios post request returning 403 when sending firebase notification

Hi I am trying to send notification to my app using firebase post method its working fine in postman but when I try to do post method in my app its returning 403. I tried implementing another get request its working fine so no problem with axios setup.
export const postData = function (url, payload) {
return AXIOS.post(url, payload, config);
};
let config = {
headers: {
'Content-Type': 'application/json',
"Authorization" : "key= *****myKey****"
}
};
Here is my post mehtod
let body = {
"to": "******myTokeb*******",
"notification": {
"title": "Title here",
"body": "R(body)",
"mutable_content": true,
"sound": "Tri-tone"
}
};
postData("http://fcm.googleapis.com/fcm/send",body).then((d)=>{
console.log("d",d)
}).catch((e)=>{
console.log("e",e);
});
Error
Error: Request failed with status code 403
at createError (D:\projects\fiver\Roeyat\node_modules\axios\lib\core\createError.js:16)
at settle (D:\projects\fiver\Roeyat\node_modules\axios\lib\core\settle.js:17)
at EventTarget.handleLoad (D:\projects\fiver\Roeyat\node_modules\axios\lib\adapters\xhr.js:61)
at EventTarget.dispatchEvent (D:\projects\fiver\Roeyat\node_modules\event-target-shim\dist\event-target-shim.js:818)
at EventTarget.setReadyState (D:\projects\fiver\Roeyat\node_modules\react-native\Libraries\Network\XMLHttpRequest.js:567)
at EventTarget.__didCompleteResponse (D:\projects\fiver\Roeyat\node_modules\react-native\Libraries\Network\XMLHttpRequest.js:389)
at D:\projects\fiver\Roeyat\node_modules\react-native\Libraries\Network\XMLHttpRequest.js:502
at RCTDeviceEventEmitter.emit (D:\projects\fiver\Roeyat\node_modules\react-native\Libraries\vendor\emitter\EventEmitter.js:189)
at MessageQueue.__callFunction (D:\projects\fiver\Roeyat\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:425)
at D:\projects\fiver\Roeyat\node_modules\react-native\Libraries\BatchedBridge\MessageQueue.js:112
Use HTTPS in postData
That will work!

Redirect URL in push notification on PWA

Currently, I'm starting a PWA in Angular. I need to intercep some push notifications and redirect to this application when I click on the notification. I'm using Firebase for the push server.
Today, I can receive push notifications but when i click on one of them, I'm not redirected.
I send my request with Postman, my HTTP request is like :
POST /fcm/send HTTP/1.1
Host: fcm.googleapis.com
Authorization: key=XXXX
Content-Type: application/json
{
"to":"XXXX",
"content_available": true,
"notification": {
"title": "hello",
"body": "test message",
"data": {
"url": "http://myurl.com"
}
}
}
In my web application, I receive the following datas :
data:
gcm.notification.content_available: "true"
gcm.notification.data: "{"url":"http:\/\/myurl.com"}"
extra: "juice"
from: "300398521917"
notification:
title: "hello"
body: "test message"
collapse_key: "do_not_collapse"
And, when I click on the receive notification, my application intercept the event and log :
action: ""
notification:
actions: []
badge: ""
body: "test message"
data: null
dir: "auto"
icon: ""
image: ""
lang: ""
renotify: false
requireInteraction: false
silent: false
tag: ""
timestamp: 1582539931548
title: "hello"
vibrate: []
I would like to refind my url in the data part. Anybody have an idea about this ?
I have tried like below its worked for me
{
"to":"XXXX",
"content_available": true,
"notification": {
"title": "hello",
"body": "test message",
"click_action": "https://example.com"
}
}
self.registration.showNotification method takes notificationOptions as parameter. So you can pass data object (that will have url and other custom properties that you want to pass) to inside notificationOption object then in notificationclick listener, get that object event.notification.data and access all custom properties there.This way you can url to listener.
messaging.onMessage(function(payload){
var dataObj = payload.data;
dataObj.someCustomProperty = "xyz";
const notificationOptions = {
data: dataObj
};
self.registration.showNotification(payload.title,
notificationOptions);
)
self.addEventListener('notificationclick', function(event){
const nUrl = event. notification.data.customProperty;
})

How to receive FCM push notifications in service worker in Chrome Extension

I'm sending an FCM push notification from a Firebase backend to a Chrome Extension. I get it to show successfully in my Chrome Extension when it's in focus. I want it to show even if the Extension isn't in focus, but I can't get the service worker that's supposed to handle the notification even to fire.
I followed the Google tutorial to set up my JavaScript Chrome Extension client. I already tried this solution to not include a "notification" payload in my message, and this solution to register the worker manually (even though the tutorial doesn't say anything about either), but to no avail.
My service worker firebase-messaging-sw.js looks like this:
importScripts('https://www.gstatic.com/firebasejs/5.8.2/firebase.js');
var config = {
...
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload.data);
var notificationTitle = 'Background Message Title';
var notificationOptions = {
body: 'Background Message body.',
icon: '/firebase-logo.png'
};
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
This is the POST request I use to send notifications (obviously with the correct SERVER_KEY and USER_TOKEN values):
POST /fcm/send HTTP/1.1
Host: fcm.googleapis.com
Content-Type: application/json
Authorization: key=<SERVER_KEY>
Cache-Control: no-cache
{
"data": {
"title": "Firebase",
"body": "Firebase is awesome",
"click_action": "http://localhost:5000/",
"icon": "http://localhost:5000/firebase-logo.png"
},
"to": "<USER_TOKEN>"
}
How do I get the service worker to receive the push notification and display it?
Thanks in advance :)
You can use Push API in service worker (firebase-messaging-sw.js):
importScripts('https://www.gstatic.com/firebasejs/7.2.2/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.2.2/firebase-messaging.js');
var config = {
...
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
this.onpush = event => {
console.dir(event.data.json());
// Here you can use event.data to compose Notification
// #see https://www.w3.org/TR/push-api/#pushmessagedata-interface
};

How to get permissions / scope for Google Apps Script to Firebase Cloud Messaging HTTP v1 API?

I am trying to send a Firebase Cloud Message from Google Apps Script. I have followed the following questions & links & assembled the following code:
Get 403 response with the "new" Firebase Cloud Messaging API
The res|error I am receiving is:
{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"status": "PERMISSION_DENIED"
}
}
My Code in Google Apps Script is:
function sendFCM(text){
text = {
"message": {
"topic": "news",
"notification": {
"title": "Breaking News",
"body": "New news story available."
},
"data": {
"story_id": "story_12345"
}
}
}
var projectId = "xxxxxxx";
var apiUrl = "https://fcm.googleapis.com/v1/projects/"+projectId+"/messages:send";
var authKey = "AAAU.......Cs";
var token = ScriptApp.getOAuthToken();
var options = {
'method' : 'post',
'contentType': 'application/json',
'muteHttpExceptions' : true,
'payload' : JSON.stringify(text),
headers:{Authorization: "Bearer "+ token},
};
var res = UrlFetchApp.fetch(apiUrl, options);
Logger.log(res);
}
Script's properties > User Scopes list follwoing:
https://www.googleapis.com/auth/firebase.database
https://www.googleapis.com/auth/script.external_request
https://www.googleapis.com/auth/spreadsheets
https://www.googleapis.com/auth/userinfo.email
FCM & GCM Api is enabled in project's developer console.
Edit:
From Ref's comment, I added the following scope to app manifest:
https://www.googleapis.com/auth/firebase.messaging
Upon Run, it asked me to authorize & now the response is an instance of a Message. But still I do not know how to define a to device i.e. to which device the message should go.
{
"name": "projects/send-xxxx3/messages/866xxxxx92"
}

Firebase - notificationclick event not receiving payload

I'm struggling with this problem for more than a week... We have implemented push message in Chrome by using Firebase and a Service Worker. Everything works just fine, the messages are being sent and received correctly with the payload. On the service worker, we handle the push message to display a notification and the notificationclick event to send the user to a specific URL when clicking on it, then close the notification.
The problem is with 'old' notifications: if a user receives a message but doesn't clicks on it right away, it keeps there for a while then after some time (not sure how much) he clicks the notification - he gets redirected to https://[domain]/firebase-messaging-sw.js
We have traced the entire process: the notification gets received with all the info properly (the url is also correct, actually if he clicks right when the message is received it works just fine). But if the notification lives there for a while it gets 'emptied'.
The message being sent is pretty simple (just for showing there are no TTLs, nor expiration parameters being used). The curl command looks like that:
curl -X POST
-H "Authorization: key=[SERVER API KEY]"
-H "Content-Type: application/json"
-d '{
"notification":{
"click_action":"[URL to be redirected]",
"icon":"[A custom image]",
"title":"[News title]"},
"to":"/topics/[A topic]"
}'
"https://fcm.googleapis.com/fcm/send"
This is the code for processing the push message on the service worker:
self.addEventListener('push', function(event) {
console.log('Push message received', event);
var data = {};
if (event.data) {
data = event.data.json();
}
event.stopImmediatePropagation();
showNotification(data.notification);
});
function showNotification(notification) {
var click_action = notification.click_action; //<-- This is correct!
var options = {
body: notification.body,
icon: notification.icon,
subtitle: notification.subtitle,
data: {
url: click_action
}
};
if (self.registration.showNotification) {
return self.registration.showNotification(notification.title, options);
}
}
And the code for managing notificationclick event is pretty straightforward:
self.addEventListener('notificationclick', function(event) {
var url = '';
try {
url = event.notification.data.url; // <-- event.notification is null randomly!!
} catch (err) {}
event.waitUntil(self.clients.openWindow(url));
});
Is there any reason for loosing the payload after a certain time on the service worker context? Is this time specified on any documentation somewhere?
Thanks in advance for your help!
//payload of push message
{
"notification": {
"title": data.title,
"body": data.text,
"click_action": url,
"tag": "",
"icon": ""
},
"to": token
}
//in service woker
self.addEventListener("notificationclick", (event) => {
event.waitUntil(async function () {
const allClients = await clients.matchAll({
includeUncontrolled: true
});
let chatClient;
for (const client of allClients) {
if (client['url'].indexOf(event.notification.data.FCM_MSG.notification.click_action) >= 0) {
client.focus();
chatClient = client;
break;
}
}
if (!chatClient) {
chatClient = await clients.openWindow(event.notification.data.FCM_MSG.notification.click_action);
}
}());
});
so in this basically, on click of notification you are redirected to application ,and if the application is not open you are opening the application in new tab , as you are concerned that in event you are not able to get the click_action, could you try event.notification.data.FCM_MSG.notification.click_action by using this and see if you are getting the url, and add the event listener in beginning of service worker https://github.com/firebase/quickstart-js/issues/102

Resources