How to use apns-collapse-id with FCM? - ios

I know this question have been asked many times but none of the answers work for me. Some of the questions dont even have an answer.
I am try to bundle or group similar notifications on ios. I am using FCM Cloud Functions to trigger notifications.
Following are the methods i tried by
const payload = {
notification: {
title: "Your medical history is updated" + Math.random(),
tag: "MedicalHistory",
},
data: {
click_action: "FLUTTER_NOTIFICATION_CLICK",
sound: "default",
status: "done",
},
};
const patchedPayload = Object.assign({}, payload, {
apns: {
headers: {
"apns-collapse-id": "MedicalHistory",
},
},
});
const options = {
priority: "high",
collapseKey: "MedicalHistory",
};
await admin
.messaging()
.sendToDevice("MY_TOKEN", patchedPayload, options);
The above code does not work
const payload = {
notification: {
title: "Your medical history is updated" + Math.random(),
tag: "MedicalHistory",
},
data: {
click_action: "FLUTTER_NOTIFICATION_CLICK",
sound: "default",
status: "done",
},
apns: {
headers: {
"apns-collapse-id": "MedicalHistory",
},
},
};
const options = {
priority: "high",
collapseKey: "MedicalHistory",
};
await admin
.messaging()
.sendToDevice("MY_TOKEN", payload, options);
This does not work as well.
I dont understand where to put the apns-collapse-id. The cloud functions sample also does not show this. Neither i could find doc with code on this

I recommend using the latest send function from the firebase-admin lib, usage described here.
It seems to work fine and somewhat easier to apply.
An example of a message with android/ios specific headers:
// common data for both platforms
const notification = {
title: 'You liked!',
body: 'You really liked something...',
}
const fcmToken = '...'
// android specific headers
const android = {
collapseKey: '0'
}
// ios specific headers
const apns = {
headers: {
"apns-collapse-id": '0'
}
}
// final message
const message = {
token: fcmToken,
notification: notification,
android: android,
apns: apns,
}
// send message
admin.messaging().send(message).catch(err => console.error(err));

Related

Flutter with Firebase Messaging. iOS device doesn't receive data only messages

I'm sending data-only message from Cloud functions
I tried this solution: https://github.com/FirebaseExtended/flutterfire/issues/3395#issuecomment-683973108
Here are the option sendings from Cloud Functions:
{
android: {
priority: "high",
},
apns: {
payload: {
aps: {
contentAvailable: true,
},
},
headers: {
"apns-push-type": "background",
"apns-priority": "5",
"apns-topic": "io.flutter.plugins.firebase.messaging", // bundle identifier
},
},
}
And here the code which handle messages. (I want to create a notification from the client not from the server)
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel',
'High Importance Notifications',
'This channel is used for important notifications.',
importance: Importance.max,
);
class BackgroundHandler {
static const IOSNotificationDetails iosNotificationDetails =
IOSNotificationDetails(subtitle: 'notification');
static final AndroidNotificationDetails androidNotificationDetails =
AndroidNotificationDetails(channel.id, channel.name, channel.description);
}
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('It works');
print(message);
FlutterLocalNotificationsPlugin().show(0, 'notification', 'new notification', NotificationDetails(android: BackgroundHandler.androidNotificationDetails,
iOS: BackgroundHandler.iosNotificationDetails));
NotificationManager.handleNotificationData(message.data);
});
On Android it works perfectly and it works even with notification, but nothing happens with data only messages.

How to create voip push notification from Node.js server

I want to send voip push to my iOS app when its not active, and I tried to use apn module from this solution but it did not work for me.
I followed official apple docs about voip push here but still have some problems to send it from the server.
I also tried to send it trough AWS sns service but got normal push for notification and etc.
What do I do wrong?
Right now my code is :
here I do format for sns item
const formatVoipPushNotificationsToSend = (type, header, launchId, sender, to = '', device_token, token) => {
const headers = {
':method': 'POST',
'apns-topic': '************.voip', //application bundle ID
':scheme': 'https',
':path': `/3/device/${device_token}`,
'authorization': `bearer ${token}`,
'apns-push-type': 'voip',
};
const aps = {
alert: {
title: header,
body: 'text' || null
},
itemId: type,
from: sender || null,
to,
launchId: launchId || null,
'content-available': 1
};
return { aps, headers };
};
and then I pass the item here and send it to the app with sns endpoint.
const pushNotifications = (item, arn, userId) => {
const payload = JSON.stringify(item);
const snsMessage = {};
snsMessage[SNS_PAYLOAD_KEY] = payload;
const params = {
Message: JSON.stringify(snsMessage),
TargetArn: arn,
MessageStructure: 'json'
};
const eventBody = item.aps.itemId ? {
[EVENT_TYPES.PUSH_SEND]: item.aps.itemId
} : {};
AmplitudeService.logEvent(EVENT_TYPES.PUSH_SEND, userId, eventBody);
return snsClient.publish(params).promise();
};
I'm using a slightly different approach:
var apn = require('apn');
const { v4: uuidv4 } = require('uuid');
const options = {
token: {
key: 'APNKey.p8',
keyId: 'S83SFJIE38',
teamId: 'JF982KSD6f'
},
production: false
};
var apnProvider = new apn.Provider(options);
// Sending the voip notification
let notification = new apn.Notification();
notification.body = "Hello there!";
notification.topic = "com.myapp.voip";
notification.payload = {
"aps": { "content-available": 1 },
"handle": "1111111",
"callerName": "Richard Feynman",
"uuid": uuidv4()
};
apnProvider.send(notification, deviceToken).then((response) => {
console.log(response);
});

Silent remote notification to iOS from Google Cloud

To send a silent remote notification to my iOS app from Google Firebase Functions, this is my index.js file:
const functions = require('firebase-functions');
const admin = require('firebase-admin')
admin.initializeApp();
const messaging = admin.messaging();
exports.sendPushNotification = functions.https.onRequest((req, res) => {
var payload = {
"notification": {
title: 'test title 2',
body: 'test body 2.1',
icon: 'https://i.pinimg.com/236x/2f/b9/bd/2fb9bd91b530d20410744249a418240b.jpg'
}
"data": {
"aps" = {
"content-available" : 1,
};
}
}
messaging.sendToTopic("backgroundUpdate", payload).then(function (response) {
console.log(response);
res.send(response);
}).catch(e => {
console.log(e)
res.send(e)
})
});
But Google keeps giving me this error message:
Deployment failure:
Build failed: /workspace/index.js:13
"data": { ^^^^^^ SyntaxError: Unexpected string at new Script (vm.js:83:7) at checkScriptSyntax (internal/bootstrap/node.js:620:5) at startup (internal/bootstrap/node.js:280:11) at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3); Error ID: d984e68f
Can anyone point me to my error? I have not been able to find a solution.

iOS background notifications using Cloud Functions

I have an issue getting data when app goes in background. I'm using Firebase Cloud functions and I think something I didn't code correctly in NodeJS. I have tried many examples and solutions like putting:
content_available: true and priority: 'high' but nothing seems to work. I have to note that:
Notifications are arriving in background and foreground but I can read data from notification in foreground but data is not fetched in background. So there is NO notifications data in background even it is displayed with sound and alert.
I think I'm doing something wrong in data payload so here is my NodeJS method:
var message = {
token: tokenID,
notification: {
title: 'ChatApplication',
body: `${myUsername} send you a message`,
},
android: {
ttl: 3600 * 1000,
notification: {
icon: 'default',
sound: 'default',
click_action: "com.yupi.chatapplication.messaging"
},
data: {
from_user: user_id,
title: 'ChatApplication',
body: `${myUsername} send you a message`
},
},
apns: {
payload: {
aps: {
alert: {
title: 'ChatApplication',
body: `${myUsername} send you a message`
},
badge: 1,
sound: 'default',
content_available: true,
mutable_content: true,
priority: 'high'
},
},
},
};
return admin.messaging().send(message)
.then((response) => {
// Response is a message ID string.
return console.log('Successfully sent message:', response);
})
.catch((error) => {
return console.log('Error sending message:', error);
});
The right field names for the Node.js SDK should be contentAvailable and mutableContent: https://firebase.google.com/docs/reference/admin/node/admin.messaging.Aps

AWS SNS sound for iOS push notification not happening

I have an SNS triggered by a lambda on AWS that generates an iOS push notification, is working fine, but the problem is that the sound is not happening...
const sns = new AWS.SNS();
var payload = {
default: ' World23',
APNS: {
aps: {
alert: 'tkt',
sound: 'default',
badge: 1
}
}
};
// first have to stringify the inner APNS object...
payload.APNS = JSON.stringify(payload.APNS);
// then have to stringify the entire message payload
payload = JSON.stringify(payload);
var params = {
Message:payload,
MessageStructure: 'json',
Subject: event.body.subject,
TargetArn:TargetArn
};
sns.publish(params, function(err,data){
if(err) {
console.error('error publishing to SNS',err);
context.fail(err);
} else {
console.info('message published to SNS',data);
done(null, data);
}
});
What is wrong with my payload?, the sound and badge are not getting set.
Cheers...
The formatting for the body needed some tweaks, also the environment was the "sandbox", will have to change for prod push notifications "APNS"...
const sns = new AWS.SNS();
var payload = {
default: notifMessage,
'APNS_SANDBOX': {
'aps': {
'alert': notifMessage,
'sound': 'default',
'badge': 1
}
},
// first have to stringify the inner APNS object...
payload.APNS_SANDBOX = JSON.stringify(payload.APNS_SANDBOX);
// then have to stringify the entire message payload
payload = JSON.stringify(payload);
var params = {
// Message: event.body.message,
Message:payload,
MessageStructure: 'json',
Subject: event.body.subject,
TargetArn:TargetArn
};
console.log('params:: ', payload);
sns.publish(params, function(err,data){
if(err) {
console.error('error publishing to SNS',err);
context.fail(err);
} else {
console.info('message published to SNS',data);
done(null, data);
}
});

Resources