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;
})
Related
I need to get a FCM registration token value which is on my device - just only to test push notification on my device before publishing it to all users. I know that there is a way to get a token during registration and send it to server, but maybe it's possible to find it in some app data without additional implementation?
Just print token to console and test it using postman.
var token = await FirebaseMessaging.getInstance().getToken();
print("token= "+token);
Then copy the token from the console and post using this api:
URI: https://fcm.googleapis.com/fcm/send
METHOD: POST
HEADERS: {
'Content-Type': 'application/json',
'Authorization': 'key=YOUR_FIREBASE_SERVER_KEY'
}
BODY: {
"notification":{
"body": "TEST MESSAGE",
"title": "TEST MESSAGE",
},
"priority": "high",
"data": {
"id": "1",
"status": "done"
},
"registration_ids": "THE_TOKEN",
},
Don't forget to close your app before sending the fcm request.
When the app is in foreground/background, everything is fine I can receive the notification, its data and the navigation works.
When the app is totally closed, I receive the notification but when I tap it I am being redirected to the main page, the data.wasTapped is not being triggered. It's like the app opens up with initial mode and I want it to go the data.confirm_page I send.
The noNotification is not working when the app is closed, any suggestions?
FCM:
FCM.onNotification(data => {
if (data.wasTapped) {
// should redirect to data.confirm_page
},
else {
// displaying a pop message, when the user confirms it sends him/her to the specified route
}
}
Push API:
{
"to": "fcm token",
"notification": {
"title": "this is the title",
"body": "this is the body",
"click_action": "FCM_PLUGIN_ACTIVITY",
"icon": "notification_icon",
"iconColor": "#e73439"
},
"android": {
"priority": "0"
},
"time_to_live_sec": 86400,
"data": {
"confirm_page": "/help",
"confirm_label": "OK",
"callback_data": {},
"reject_label": "Cancel"
}
}
I'm using FCM with firebase-admin to send a Web Push notification for multiple clients. I want to replace an older message by a new one.
This is how I'm calling it:
return await admin.messaging().sendMulticast({
tokens,
notification: {
title: "Message Title",
body: "Message body.",
},
data: {
type: "ring",
callId,
},
webpush: {
fcmOptions: {
link: process.env.PWA_APP_URL,
},
headers: {
Urgency: "high",
},
},
android: {
collapseKey: "ring",
priority: "high",
ttl: 10,
notification: {
color: "#ff0000",
defaultSound: true,
sound: "default",
lightSettings: {
color: "#ffcc00",
lightOffDurationMillis: 1000,
lightOnDurationMillis: 1000,
},
tag: "ring",
vibrateTimingsMillis: [1000, 1000],
visibility: "public",
priority: "max",
},
},
});
When the message arrives to an Android app client it's collapsed because of android.collapseKey property. But I can't get the same behavior in my web application.
According to the docs, there's a Topic option for Web notifications, but I'm not sure where to put it. I tried to use it as webpush.headers.Topic property but with no success. Messages are not collapsed in Android/Chrome.
What am I doing wrong?
I've followed collimarco's tip and could use showNotification method to collapse a notification.
In firebase-admin/server code I had to remove the notification fields in the message's payload. Now it's just a data message:
return await admin.messaging().sendMulticast({
tokens,
data: {
type: "ring",
callId,
},
});
In the web application I created a background message handler. Now I can call showNotification method when I new message arrives using tag property with renotify=true.
messaging.setBackgroundMessageHandler(function (payload) {
// ...
return self.registration.showNotification("Message Title", {
body: "Message body.",
tag: "ring",
renotify: true,
vibrate: [1000, 1000],
});
});
It would be great to have these properties set on the message payload only.
I'm using FCM for a chat app. Everytime an user receives a message, I send him a notification via FCM. If user isn't with my web app in foreground, the message handling happens in a default Service Worker that generates a notification with the parameters I've specified on the body of my request. The problem is, everytime a new push message is sent and the app is in background, browsers (tested on Chrome and Firefox) are creating a new message instead of updating the existing one. I would like to keep the already visible notification and only update its value, is that possible?
Service Worker that handles the push if app isn't in foreground:
importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.5.2/firebase-messaging.js');
firebase.initializeApp({
'messagingSenderId': '*****'
});
const messaging = firebase.messaging();
JSON body of the request sent to FCM server
{
"priority" : "normal",
"collapse_key": "demo",
"notification": {
"title": "Felicius Humble",
"body": "This is a sample message content",
"click_action": "https://****.herokuapp.com",
"icon": "****"
},
"to": "****",
"data": {
"id": 7,
"timestamp": 1493573846692,
"content": "teste",
"type": "MESSAGE",
"direction": "OUTPUT",
"sender": {
"id": 5,
"name": "Felicius Humble",
"email": "****#gmail.com",
"gender": "MALE",
"picture": "****",
"facebookID": "****",
"fcmToken": "****",
"accessToken": "****"
},
"chatID": 3
}
}
Ok, so I've found this that shows all options available for the json body. For what I need I just need to add "tag" param on notification obj in my json body. If you want to update the notification, sent it with the same tag. Example:
{
"notification": {
"title": "",
"body": "",
"click_action": "",
"icon": "",
"tag" : "this must be the same for the notifications you want to update"
},
"to": "****",
"data": {}
}
}
There are scenarios where you might want a replacing notification to notify the user rather than silently update. Chat applications are a good example. In this case you should set tag and renotify to true.
write this code on your sw.js
const title = 'Notification 2 of 2';
const options = {
tag: 'renotify',
renotify: true
};
registration.showNotification(title, options);
You can test demo on here by clicking in renotify button
I am using Ionic 2 with HTTP native module to make a post request to FCM server for push notifications. The code I am using is:
HTTP.post(
"https://fcm.googleapis.com/fcm/send",
{
"notification": {
"title": "Notification title",
"body": "Notification body",
"sound": "default",
"click_action": "FCM_PLUGIN_ACTIVITY",
"icon": "fcm_push_icon"
},
"data": {
"hello": "This is a Firebase Cloud Messagin hbhj g Device Gr new v Message!",
},
"to": "device token",
},
{
Authorization: {
key: "AUTHORIZATION KEY HERE"
}
})
Its giving me an error:
Unimplemented console API: Unhandled Promise rejection:
Unimplemented console API: Error: Uncaught (in promise): [object Object]
I tried the post request with Postman, it works perfectly fine delivering push notifications.
The code with Postman is:
POST /fcm/send HTTP/1.1
Host: fcm.googleapis.com
Content-Type: application/json
Authorization: key=Authorisation Key
Cache-Control: no-cache
Postman-Token: 446e253b-179a-d19b-21ea-82d9bb5d4e1c
{
"to": "Device Token",
"data": {
"hello": "This is a Firebase Cloud Messagin hbhj g Device Gr new v Message!",
}
"notification":{
"title":"Notification title",
"body":"Notification body",
"sound":"default",
"click_action":"FCM_PLUGIN_ACTIVITY",
"icon":"fcm_push_icon"
},
}
Questions:
I am unable to add content-type to the header in the HTTP post request, but it works with postman.
If I try to add a function(response) { to get the response from the server, it gives me an error. The documentation for the same is at https://github.com/wymsee/cordova-HTTP
why are you using HTTP native module? Angular has a built in Http.
Using this one (importing HttpModule from #angular/http in your NgModule) you can just call
import { Http, Headers } from '#angular/http';
......
constructor(public http: Http) { }
sendPushNotification(deviceId: string) {
let url = 'https://fcm.googleapis.com/fcm/send';
let body =
{
"notification": {
"title": "Notification title",
"body": "Notification body",
"sound": "default",
"click_action": "FCM_PLUGIN_ACTIVITY",
"icon": "fcm_push_icon"
},
"data": {
"hello": "This is a Firebase Cloud Messagin hbhj g Device Gr new v Message!",
},
"to": "device token"
};
let headers: Headers = new Headers({
'Content-Type': 'application/json',
'Authorization': 'key='+this.someKey
});
let options = new RequestOptions({ headers: headers });
console.log(JSON.stringify(headers));
this.http.post(url, body, headers).map(response => {
return response;
}).subscribe(data => {
//post doesn't fire if it doesn't get subscribed to
console.log(data);
});
}
push.on('notification', (data) => {
if (data.additionalData.foreground) {
// if application open, show popup
let confirmAlert = this.alertCtrl.create({
title: data.title,
message: data.message,
buttons: [{
text: 'Ignore',
role: 'cancel'
}, {
text: 'Go to',
handler: () => {
//TODO: Your logic here
this.navCtrl.setRoot(EventsPage, {message: data.message});
}
}]
});
confirmAlert.present();
} else {
//if user NOT using app and push notification comes
//TODO: Your logic on click of push notification directly
this.navCtrl.setRoot(EventsPage, {message: data.message});
}
});
push.on('error', (e) => {
alert(e);
});
});