I have a small issue. I am trying to test my push notification feature but I can't figure it out. I set up a webRTC page that I'm using to send the notification (I don't own 2 IOS devices). All the certificates/keys were generated using fastlane actions (match and pem). I am aware I'm using a production feature for the apnOptions and I generated the correct certificates. When I write some gibberish on the key or teamID, I get errors so that means my certificate should be alright. The bundle identifier is exactly the one that appears on the developer Apple page.enter code here
Here are my token and my notification:
var apnProvider = new apn.Provider({
token: {
key: "cert/key.p8",
keyId: "#",
teamId: "#"
},
production: true
});
if (deviceToken) {
if (platform === 'ios') {
let note = new apn.Notification()
note.alert = 'Hello World'
note = Object.assign(note, {
// Expires 1 hour from now.
expiry: Math.floor(Date.now() / 1000) + 3600,
badge: 3,
payload: payloadBody,
topic: "org.#.#"
})
apnProvider.send(note, deviceToken).then((result) => {
console.log('APNPROVIDER RESULT', `PLATFORM: ${platform}, RESULT:${JSON.stringify(result)}`)
})
Thank you very much for your help!
I found out in the end. It turned out that if I use a voip bundle I need to add at the end of the bundle .voip. So, a bundle would look something like org.test.Test.voip. I'm done..
In my case, the problem was, Server was taking push kit device token i.e. voIP token, and the bundle id was "com.something".
Solution: For voIP type of notifications user, "com.something.voip" topic/bundle id.
IOS follows proper format for push notification. If you do not follow proper format your notifications won't be delivered. There should be a aps tag also.
{
"aps": {
"alert": "Hello World",
"sound": "default"
},
"customData": {
"CustomKey": "CustomValue",
}
}
You can follow this link for reference
https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/generating_a_remote_notification
Double check the Topic Name, I've encountered this problem with a typo in the Topic Name.
Related
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've set up react-native-onesignal on my project to implement Push Notification using OneSignal.
It is possible to test Push Notification on iOS simulators since Xcode 11.4 Beta. I created JSON formatted apns file to test Push Notification on Simulator and it worked very well.
But how can I emulate OneSignal Push Notification?
I followed OneSignal Documentation and want to receive Push Notification which is sent from OneSignal Dashboard.
Here's what I've implemented on my App.tsx file.
const initializeOneSignal = () => {
OneSignal.setLogLevel(6, 0);
OneSignal.init("MY_ONESIGNAL_APP_ID", {
kOSSettingsKeyAutoPrompt: false,
kOSSettingsKeyInAppLaunchURL: false,
kOSSettingsKeyInFocusDisplayOption: 2,
});
OneSignal.inFocusDisplaying(2);
OneSignal.promptForPushNotificationsWithUserResponse(myiOSPromptCallback);
OneSignal.addEventListener('received', onPNReceived);
OneSignal.addEventListener('opened', onPNOpened);
OneSignal.addEventListener('ids', onPNIds);
};
useEffect(() => {
initializeOneSignal();
return () => {
OneSignal.removeEventListener('received', onPNReceived);
OneSignal.removeEventListener('opened', onPNOpened);
OneSignal.removeEventListener('ids', onPNIds);
};
}, []);
const onPNReceived = notification => {
console.log('Notification received: ', notification);
};
const onPNOpened = openResult => {
console.log('Message: ', openResult.notification.payload.body);
console.log('Data: ', openResult.notification.payload.additionalData);
console.log('isActive: ', openResult.notification.isAppInFocus);
console.log('openResult: ', openResult);
};
const onPNIds = device => {
console.log('Device info: ', device);
};
const myiOSPromptCallback = permissions => {
console.log('Permissions: ', permissions);
};
I cannot see any logged message when I sent Push Notification from my OneSignal Dashboard.
Do I need to do any trick in apns file?
Any help would be appreciated.
tl;dr you can't send a real notification to a simulator. You can only send mocked notifications to a simulator
Your server is oblivious of a simulator, because simulators don't have device tokens. Apple decided not to give it one. I suppose this was so users can't fake their device token and get notifications on their simulator...
The 11.4 simply allows the drag and drop of a APNs payload into the simulator without any mention of device token.
You can check out this article on Medium enter link description here.
This article helped me test oneSignal push notifications on my iOS simulator and figure out the deep linking issue.
Here are my steps:
Create a payload.apns file on your desktop
Put the following code inside it:
{
"Simulator Target Bundle": "com.example.app",
"aps": {
"alert": {
"title": "Push Notification",
"subtitle": "Test Push Notifications",
"body": "Testing Push Notifications on iOS Simulator",
}
},
"custom": {
"i": "notificationId as UUID",
"a": {"deeplinkKey": "{\"deeplinkDetailKey\":\"deeplinkDetailValue\"}", "launchURL": "example://collection/myCollectionId/type/1"}
}
}
Remember to replace com.example.app with your app bundle ID.
Run your app on the simulator, then close the app and keep metro open
Drag and drop payload.apns file on the simulator, you will see the notification to click on it. If you have done the 3rd step right, you should be redirected to your app
(Optional) If you need to test a deep link with the push notification, I haven't yet found the key oneSignal uses, but as you see in the .apns file above, I added a launchURL to the a which represents additionalData and handled catching and opening it manually in the app to test what's wrong with the deep link.
(Optional) To open a deep link in your app, you can use Linking API from react-native:
import {Linking} from 'react-native'
Linking.openURL("Path/to/launchURL")
Starting from iOS 13 and watchOS 6 Apple requires the presence of the header apns-push-type (the value of this header can be alert or background) for push notification.
According to Apple documentation:
The value of this header must accurately reflect the contents of your notification's payload. If there is a mismatch, or if the header is missing on required systems, APNs may delay the delivery of the notification or drop it altogether.
HEADERS
- END_STREAM
+ END_HEADERS
:method = POST
:scheme = https
:path = /3/device/xxxxxx
host = api.sandbox.push.apple.com
authorization = bearer xxx
apns-id = xxx-xxx-xxx
apns-push-type = alert
apns-expiration = 0
apns-priority = 10
apns-topic = com.example.MyApp
DATA
+ END_STREAM
{ "aps" : { "alert" : "Hello" } }
see Apple doc
Unfortunately using azure notification hub I can only define apscontent but not the header.
{ "aps": { "alert":"Alert message!", "content-available": 1 }, "CustomData": "$(CustomData)" }
How is it handled by azure notification hub?
How can I specify the type of the notification?
After some experiments and a little bit of investigation, this is the current Azure server behavior...
The server inspects the contents of the notification to infer the correct value.
If "content-available": 1 is present and "alert" is missing then the "apns-push-type" = "background" is added to the header.
If a valid "alert" is present then the "apns-push-type" = "alert" is added to the header.
So take care of having a valid APNS JSON body, with correctly populated content-available/alert properties.
See this discussion thread for more info
UPDATE 2019-10-15:
Currently there are some problems with background silent notification
See the following discussion:
https://github.com/Azure/azure-notificationhubs-dotnet/issues/96
UPDATE 2019-11-25:
The server was rejecting installations against APNS that included headers. Now this issue is fixed and the silent notification should work as expected.
This answer is not accurate, background push is not working on azure right now. The headers need to be included during sending a push as shown below and also the hub needs to be configured with a key and not a certificate:
var backgroundHeaders = new Dictionary<string, string> { { "apns-push-type", "background" }, { "apns-priority", "5" } };
Dictionary<string, string> templateParams = new Dictionary<string, string>();
// populated templateParams
var notification = new TemplateNotification(templateParams);
notification.Headers = backgroundHeaders;
// the second parameter is the tag name and the template name as we have it registered from the device.
var resBack = await hubClient.SendNotificationAsync(notification, tags);
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'm trying to develop a Push Notifications feature in an app by first trying to send them through the app, which I've heard masterKey is required for. Although I haven't heard of anywhere I can put the masterKey into my Xcode project.
Is there a specific location to include the masterKey in my Xcode project? Can masterKey even be used in a swift project?
Yes, masterKey must be used to send push notification but Parse-server is not going to support pushing from client apps due to security issues. So, you need to write a cloud function for it. A simple cloud function that send pushes to all users who have installed your app looks like this.
Parse.Cloud.define("push", function(request, response){
var message = request.params.message;
//Pushes work with Installation table
//So, you need to select to whom you want to push
var installationQuery = new Parse.Query(Parse.Installation);
//You should set expiration time when push will be expired
//This is optional
var expDate = new Date();
expDate.setDate(expDate.getDate() + 1); //The notification will expire in 1 day
//Setting up push data
var data = {"badge": "Increment", "sound": "default"};
data['alert'] = message;
//Sending push
Parse.Push.send({
where: installationQuery,
data: data,
expiration_time: expDate
},{
success: function () {
response.success("Pushed successfully");
},
error: function (error) {
response.error(error);
},
useMasterKey: true
});
});
In your iOS app,
PFCloud.callFunctionInBackground("push", withParameters: ["message":"Pushing from cloud code"]) {
(response: AnyObject?, error: NSError?) -> Void in
//Do stuffs
}
Hope this helps
masterKey is added server side. depending on your setup or instance you can set it up in your index.js file.
// With the value of your app's Master Key completed:
masterKey: process.env.MASTER_KEY || '<your app's Master Key>'
If you are using environmental variables you can set your json file with this value:
"PARSE_SERVER_MASTER_KEY": "#####",
Should be in the same file where you set the paths to the certificates.