I am using push plugin in ionic 3 app, everything is working fine but from my server end we are sending one message at a time and im receiving message to iPhone, but old message should overwrite with new message or once we receive new message then old message is clear automatically..
I'm not able to find anything related to this, please anybody help me to solve this.
const options: PushOptions = {
android: {},
ios: {
alert: 'true',
badge: true,
sound: 'false'
},
windows: {},
browser: {
pushServiceURL: 'http://push.api.phonegap.com/v1/push'
}
};
const pushObject: PushObject = this.push.init(options);
pushObject.on('notification').subscribe((notification: any) =>
console.log('Received a notification', notification));
It sounds like you aren't sending your messages configured to be "collapsible". By default each message will be distinct, not overwriting the last message. FCM documents this well:
https://firebase.google.com/docs/cloud-messaging/concept-options
Non-collapsible and collapsible messages
A non-collapsible message
denotes that each individual message is delivered to the device. A
non-collapsible message delivers some useful content, as opposed to a
collapsible message like a content-free "ping" to the mobile app to
contact the server to fetch data.
...
A collapsible message is a message that may be replaced by a new message if it has yet to be delivered to the device.
...
Or if you are not using FCM, here's a reference to Apple's APN docs directly.
To allow the coalescing of similar notifications, you can include a
collapse identifier within a notification request. Normally, when a
device is online, each notification request that you send to APNs
results in a notification delivered to the device. However, when the
apns-collapse-id key is present in your HTTP/2 request header, APNs
coalesces requests whose value for that key is the same. For example,
a news service that sends the same headline twice could use the same
collapse identifier value for both requests. APNs would then coalesce
the two requests into a single notification for delivery to the
device. For details on the apns-collapse-id key
Update with some code details:
public void sendMessage(String title, String body, Map<String, String> data, boolean shouldCollapse) {
PlatformConfiguration platformConfig = new PlatformConfiguration(30);
if (shouldCollapse)
messageBuilder.setAndroidConfig(platformConfig.getCollapsibleAndroidConfig("test")).setApnsConfig(platformConfig.getCollapsibleApnsConfig("test"));
...
public ApnsConfig getCollapsibleApnsConfig(String collapseKey) {
return getCoreApnsConfig().putHeader("apns-collapse-id", collapseKey)
.setAps(getNonCollapsibleApsBuilder().setCategory(collapseKey).setThreadId(collapseKey).build()).build();
}
public AndroidConfig getCollapsibleAndroidConfig(String collapseKey) {
return getCoreAndroidConfig().setCollapseKey(collapseKey)
.setNotification(
getNonCollapsibleAndroidNotificationBuilder().setTag(collapseKey).build()).build();
}
Related
I'm using the firebase Message class to create push notifications for a react native app. I want the notification to take users to a specific screen of the app. Right now tapping on the push notification just takes users to the last screen they were on before they back-grounded the app. I'm testing this on my iOS device. How can I embed a specific deep link in the message? Would I use setApnsConfig(ApnsConfig apnsConfig) or setFcmOptions(FcmOptions fcmOptions)?
I would use the APNS config since this is for an iOS app:
https://firebase.google.com/docs/reference/admin/java/reference/com/google/firebase/messaging/ApnsConfig.Builder
You could approach it different ways, but you could either include a URL in the header field, and use it for custom deep link logic, or you can have custom data in the putCustomData(String key, Object value) and then have your app process that info to deep link into the correct part of your app.
Your app would process this notification in the application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623013-application
I had integrated this feature in an app I made in react native aswell. Look at my solution below.
As you can see in the app I am waiting for a notification to come on and I check if it has a type available. My notifications are always routed to another page. In my case its the same page but I set a route as datatype in my payload.
After that you can use that route payload with your naviogator library in my case react-navigation to navigate to the correct screen.
You should chose which trigger works best for you ether onNotificationOpenedApp or getInitialNotification.
useEffect(() => {
// Assume a message-notification contains a "type" property in the data payload of the screen to open
messaging().onNotificationOpenedApp((remoteMessage) => {
console.log(
"Notification caused app to open from background state:",
remoteMessage
);
//navigation.navigate(remoteMessage.data.type);
});
// Check whether an initial notification is available
messaging()
.getInitialNotification()
.then((remoteMessage) => {
if (remoteMessage) {
console.log(
"Notification caused app to open from quit state:",
remoteMessage
);
const route = remoteMessage?.data?.route;
navigation.navigate(route, {
data: remoteMessage.data,
});
}
})
.catch((error) => console.log("Caught ", error));
}, []);
My project had working notifications previously and I can't trace any changes to the payload I've been sending. I've referenced the docs and can't see any issues with my payload. The exact error I am getting is
Request contains an invalid argument
let payload = {
token : oUser.devicetoken,
data : {
referenceid : chatid,
referencetype : 'chat',
referencename : oSender.displayname,
receiverid : userid,
type : 'message',
notificationid : res,
title : title,
body : `${oSender.displayname} : ${body}`
},
android : {
priority : 'high'
},
apns : {
payload : {
aps : {
'content-available' : 1
}
},
headers : {
'apns-push-type' : 'background',
'apns-priority' : '5',
'apns-topic' : 'llc.attebyte.partyme'
}
}
};
My current payload:
After taking a fresh look at the Apple docs for notifications I noticed that I should be using content-available. I had previously been using contentAvailable: true (and it was working). Neither one is working anymore.
There are multiple questions regarding this problem already. This one being the best I've found: firebase cloud messaging Request contains an invalid argument
I verified that the token is correct by sending the device a test notification from the firebase console. I don't think I should be hitting the size limit of 4kb, the message I am sending for testing is something along the lines of 'test' or 'hello' (also the issue is IOS specifi). I've also verified that the headers I am sending are current with the Apple docs.
I can't figure out any differences that would cause notifications to stop working within the last week or so. I know they were working then and I've gone through my Github history to verify the payload hasn't changed (besides my change to content-available I made today while testing.)
While Google takes its time to fix this, we could successfully send silent notifications using the legacy app server protocols:
https://firebase.google.com/docs/cloud-messaging/send-message#send-messages-using-the-legacy-app-server-protocols
The endpoint we are using is https://fcm.googleapis.com/fcm/send.
Here you can find the message structure (note that is quite different from the current API):
https://firebase.google.com/docs/cloud-messaging/http-server-ref
And here how to authorize the requests:
https://firebase.google.com/docs/cloud-messaging/auth-server#authorize-http-requests
Hope it helps while we wait for a definitive fix.
I can send test notifications from Firebase console to my app both on iOS and Android. Therefore, my app is set up properly to receive push notifications on both platforms. However, when I use a cloud function to send notifications. Only, notifications on the Android device are received. No notifications show up on the iOS device. I suspect this may be related to the way that I create the payload in my cloud function. Maybe I am missing something for iOS. If you could give me some tips, that would be great.
I checked if the deviceToken for the iOS device is correct and it was correct.
I sent a test message using firebase console to the same deviceToken for the iOS device and the notification was delivered.
Therefore, I concluded my problem may arise from the cloud function I wrote. Thus, I share below the cloud function:
exports.notifToApp = functions.database.
ref(`/memInfo/{memId}/notifChoice/`).onWrite((snap, context) => {
//send only if exists and new notification OR if doesn't exist
if ((snap.before.exists() && (snap.after.val() !== snap.before.val())) || !snap.before.exists()) {
//get notification body
const notificationTitle = snap.after.val().memName;
const notificationText = snap.after.val().notifText;
//get and loop over notification subscribers
return admin.database().ref(`/notifics/${context.params.memId}/notifSubs/`).once("value", subs => {
if (subs.exists()) {
return subs.forEach(sub => {
//payload for notification
const payload = {
"notification":{
"title": notificationTitle,
"body": notificationText,
"sound": "default",
"click-action": "FCM_PLUGIN_ACTIVITY",
"priority": "high"
}
}
//deliver notification
return admin.messaging().sendToDevice(sub.val().deviceToken, payload).catch(e => {console.log(e);});
});
} else { //end: if returned any value
return 0;
}
});// end: get and loop over notification subscribers
} else { //end: send only if exists and new notification OR if doesn't exist
return 0;
}
});
I do not get any error messages. Function completes successfully with status "OK."
I test using two devices: one android and one iOS. Both device tokens are saved correctly in the database for the cloud function to retrieve and use for sending messages.
I see the notification on the Android device running my app. I wish the notification to show up on the iOS device running the same app.
Test message notification sent from the firebase console shows up on both devices correctly.
I realized that sendToDevice() used the legacy version of payload. I used send() in my function to use the newer version. (see answer: stackoverflow)
admin.messaging().send(payload).catch(e => console.log(e));
I changed the payload to include platform specific fields according to the latest guidelines (see firebase docs)
const payload = {
"token": sub.val().deviceToken,
"notification":{"title": notificationTitle,"body": notificationText},
"android": {"notification": {"sound": "default"}},
"apns": {"payload": {"aps": {"sound": "default"}}}
};
Now it works on both platforms.
I was finishing up an app for somebody but needed some help with the script that I wrote for sending notifications via Cloud Functions for Firebase. Below this text you can find my code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/Users/{userUid}/').onWrite(event => {
const followerUid = event.params.userUid;
const payload = {
notification: {
title: 'Update Received',
body: 'Please Check Your App',
badge: 1,
sound: 1,
}
};
return admin.database().ref('/Admin/notificationID').once('value').then(allTokens => {
if (allTokens.val()) {
// Listing all tokens.
const tokens = allTokens.value
return admin.messaging().sendToDevice(tokens, payload).then(response => {
});
};
});
});
Mainly there are only 3 issues that I am having. First of all, I am not sure if I am using the correct syntax for specifying the badge. Second of all, I don't know how to specify that I want a sound to be played for the notification. Lastly, I am unable to send the notification because the notificationID that is returned from the database is apparently incorrect even though I have a legible FCM ID stored in my database under /Admin/ with the key notificationID. I would appreciate it if one of you could help me fix these issues and get this app up and running.
Thanks,
KPS
The value for badge needs to be String:
Optional, string
Same in #1, sound value needs to be String:
Optional, string
The sound to play when the device receives the notification.
Sound files can be in the main bundle of the client app or in the Library/Sounds folder of the app's data container. See the iOS Developer Library for more information.
Hard to tell without any additional details. Are you positive that it's a valid registration token? Does it work when you send a message to it using the Firebase Console? If not, is it throwing an error?
I know there is event listener in TriggerIo to catch received push notifications from Parse:
forge.event.messagePushed.addListener(function (msg) {
alert(msg.alert);
});
But the 'msg' object contains only 'alert' and 'sound' keys...
Is there a way to receive at least a channel name to which push notification was sent? I need this to decide which view to open in my app as each channel has it's own destination. And if this is not possible, maybe there is another way to do this?
P.S I suppose it could be done by inserting some kind of 'keyword' into message it self, but I would rather avoid it.
I just realised, that there is a way to send so called JSON payload via Parse push submission form.
{
"alert" : "My message",
"additional" : "data"
}
More info: https://parse.com/questions/json-format-to-send-notification-from-parse