I am trying to use Worklight push notification to send push for a iOS+Android Application.
I created the submitNotification function in my adapter, and when I invoke it, it says that the push was sent successfully, but in reality, I have no push received in my device.
When I see the logs I can read:
Couldn't connect to APNS server
java.net.PlainSocketImpl.socketConnect(Native Method)
java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)
java.net.Socket.connect(Socket.java:529)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:570)
com.sun.net.ssl.internal.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:371)
com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:71)
com.notnoop.apns.internal.ApnsConnectionImpl.socket(ApnsConnectionImpl.java:133)
com.notnoop.apns.internal.ApnsConnectionImpl.sendMessage(ApnsConnectionImpl.java:160)
com.notnoop.apns.internal.ApnsServiceImpl.push(ApnsServiceImpl.java:46)
com.notnoop.apns.internal.AbstractApnsService.push(AbstractApnsService.java:52)
com.notnoop.apns.internal.ApnsServiceImpl.push(ApnsServiceImpl.java:36)
com.worklight.integration.notification.apns.ApplicationConnection.sendNotification(ApplicationConnection.java:84)
com.worklight.integration.notification.apns.APNSMediator.sendNotification(APNSMediator.java:85)
com.worklight.integration.notification.Mediator$4.run(Mediator.java:174)
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
java.util.concurrent.FutureTask.run(FutureTask.java:138)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
java.lang.Thread.run(Thread.java:680)
and
Couldn't send message com.notnoop.apns.EnhancedApnsNotification#96eee2c0 com.notnoop.apns.internal.ApnsConnectionImpl.socket(ApnsConnectionImpl.java:146)
com.notnoop.apns.internal.ApnsConnectionImpl.sendMessage(ApnsConnectionImpl.java:160)
com.notnoop.apns.internal.ApnsServiceImpl.push(ApnsServiceImpl.java:46)
com.notnoop.apns.internal.AbstractApnsService.push(AbstractApnsService.java:52)
com.notnoop.apns.internal.ApnsServiceImpl.push(ApnsServiceImpl.java:36)
com.worklight.integration.notification.apns.ApplicationConnection.sendNotification(ApplicationConnection.java:84)
com.worklight.integration.notification.apns.APNSMediator.sendNotification(APNSMediator.java:85)
com.worklight.integration.notification.Mediator$4.run(Mediator.java:174)
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
java.util.concurrent.FutureTask.run(FutureTask.java:138)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
java.lang.Thread.run(Thread.java:680)
then
Failed to send message com.notnoop.apns.EnhancedApnsNotification#96eee2c0... trying again
My submitNotification function :
function submitNotification(userId, notificationText) {
var userSubscription = WL.Server.getUserNotificationSubscription(
'myAdapter.MyPushEventSource', userId);
if (userSubscription == null) {
return {
result : "No subscription found for user :: " + userId
};
}
WL.Logger.debug("submitNotification >> userId :: " + userId + ", text :: "
+ notificationText);
WL.Server.notifyAllDevices(userSubscription, {
badge : 1,
activateButtonLabel : "Open",
alert : notificationText
});
return {
result : "Notification sent to user :: " + userId
};
}
Is there something wrong with my code? or with my Network ?
It was finally a network issue.
We changed our Firewall configuration to allow access to Google and Apple push servers.
For Apple Servers, you can find more details at this address : http://developer.apple.com/library/ios/#technotes/tn2265/_index.html#//apple_ref/doc/uid/DTS40010376-CH1-TNTAG41
the entire 17.0.0.0/8 address block is assigned to Apple, so you can
specify that range in your firewall rules.
Related
I'm using java TinyB to connect to a TimeFlip device with Bluetooth LE.
When trying to write to the Descriptor of the Facet Characteristic to recieve notifications I always get the error:
Exception in thread "main" tinyb.BluetoothException: GDBus.Error:org.bluez.Error.NotPermitted: Write not permitted
But when I write to the same Descriptor using gatttool it works and i get the notifications.
BluetoothGattService timeFlipService = device.find("f1196f50-71a4-11e6-bdf4-0800200c9a66", Duration.ofSeconds(5));
BluetoothGattCharacteristic facets = timeFlipService.find("f1196f52-71a4-11e6-bdf4-0800200c9a66", Duration.ofSeconds(5));
BluetoothGattDescriptor facetsConfig = facets.find("00002902-0000-1000-8000-00805f9b34fb", Duration.ofSeconds(5)); // like this ==> always null, custom method works???
if(!login(timeFlipService)) {log.error("login to TimeFlip failed");}
try{
byte[] enableNotifications = {0x01, 0x00};
facetsConfig.writeValue(enableNotifications); //when facesConfig assigned with custom method throws write not permitted error
facets.enableValueNotifications(new FacetNotification());
}
catch(NullPointerException e){
log.error("NullPointerException in " + (facets == null ? "facet characteristic" : "facet descriptor"));
}
catch(BluetoothException b){
log.error(b.getMessage());
}
}
The mentioned "custom method" just gets all Descriptor from a characteristic and returns the one matching a given uuid, as the find() method times out every time.
In Bluez you are supposed to use StartNotify to turn on notifications or indications. Bluez will do the writing of the descriptor for you but if you try to do it yourself it indeed gives an error.
in my project I use Firebase Functions to send message via FCM.
I use this API:
admin.messaging().send()
Recently and not for all token that I use to invoke it, I got this error:
Error: Requested entity was not found.
at FirebaseMessagingError.Error (native)
at FirebaseMessagingError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:39:28)
at FirebaseMessagingError.PrefixedFirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:85:28)
at new FirebaseMessagingError (/user_code/node_modules/firebase-admin/lib/utils/error.js:241:16)
at Function.FirebaseMessagingError.fromServerError (/user_code/node_modules/firebase-admin/lib/utils/error.js:271:16)
at /user_code/node_modules/firebase-admin/lib/messaging/messaging-api-request.js:140:50
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
How can I solve it ?
I'm sure some time ago it works and these errors are not.
Any changes in Firebase?
This error means the token you are trying to send the notification, doesn't exists.
You must add your send code on a try catch block, and, depending on the error, erase (or invalidate) the token on your base.
try {
...
sendYourNotification(token);
...
} catch (error) {
if (
[
'The registration token is not a valid FCM registration token',
'Requested entity was not found.',
'NotRegistered.'
].includes(error.message)
) {
// invalidate current token
// find the user and remove this token
} else {
// Log it, because is some really unexpected
}
}
I want to subscribe multiple users to a device for push notification in MFP. which i assume is not possible.
So what I want to do is i want to send my notification on the basis of deviceid ignoring user. Is this possible.
I see two methods which send notification to a device, but they still need userid is what i see.
WL.Server.notifyDevice(userSubscription, deviceId, notification);
WL.Server.notifyDeviceSubscription(deviceSubscription, notificationOptions)
Is there any other way, Please suggest.
Yes, You can send push notification targeted to deviceId using multiple ways.
You can use sendMessage API where you can specify deviceIds in Target Parameter. In this case only those deviceIds will receive the notification.
More Details about API : https://www.ibm.com/support/knowledgecenter/SSHS8R_7.1.0/com.ibm.worklight.apiref.doc/html/refjavascript-server/html/WL.Server.html#sendMessage
Send Message REST API where you need to add target as deviceIds.
The following is the payload example.
{
"message" : {
"alert" : "Test message",
},
"target" : {
"deviceIds" : [ "MyDeviceId1", ... ]
},
}
More details about API : https://www.ibm.com/support/knowledgecenter/SSHS8R_7.1.0/com.ibm.worklight.apiref.doc/rest_runtime/r_restapi_send_message_post.html
I am trying to implement push notifications using bluemix and mobilefirst. I have used the following links to implement
http://www.ibm.com/developerworks/library/mo-cordova-push-app/
http://mbaas-gettingstarted.ng.bluemix.net/hybrid#initialize-push -
When i run the the below code I am getting the following message in the console:
initPush called----------------
main.js:29 calling bluemix initialize with values----------------------
IBMBluemixHybrid.js:2956 [INFO] [DEFAULT] Hybrid initialize ["applicationid","applicationsecret","applicationroute"]
I neither see the device details reflected in the bluemix registered list. Can you please help me on this ?
var values = {
applicationId:"applicationId",
applicationRoute:"applicationRoute",
applicationSecret:"applicationSecret"
};
console.log("initPush called---------------------------------");
console.log("calling bluemix initialize with values--------------------------------");
IBMBluemix.initialize(values).then(function(status) {
console.log("IBM Bluemix Initialized", status);
return IBMPush.initializeService();
}, function (err) {
console.error("IBM Bluemix initialized failed" , err);
}).then(function(pushObj) {
function pushReceived(info) {
console.log("registerListener - " + info.alert);
alert('got a push message! ' + info.alert);
}
console.log("IBM Push Initialized", pushObj);
push = pushObj;
return push.registerDevice("LisaTest","Lisa123","pushReceived");
}, function (err) {
console.error("IBM Bluemix Push initialized failed" , err);
});
You need to replace "applicationId", "applicationRoute", and "applicationSecret" in the code
var values = {
applicationId:"applicationId",
applicationRoute:"applicationRoute",
applicationSecret:"applicationSecret"
};
with those obtained from your Bluemix backend application.
From the bluemix dashboard for your application click mobile options in the top right to see your ID and Route.
For the secret navigate to the Mobile Application Security dashboard from the link on the right, and your secret will be displayed on that page.
We are trying to run the sample app for push notifications with some modification to get it to send out a broadcast notification, but it is not getting sent.
We have modified the PushBackendEmulator code as well. The emulator invokes the submitBroadCastNotification procedure successfully and the following result is returned:
Server response :: /-secure-{"result":"Notification sent to all
users","isSuccessful":true}/
However, it appears the WL.Server.sendMessage method is not sending the message and returns. I am not able to see the server side logs either after a thorough search on the liberty server except for the messages.log on the liberty server which shows the following when WL.Server.sendMessage is called.
ht.integration.js.JavaScriptIntegrationLibraryImplementation E
FWLSE0227E: Failed to send notification. Reason: FPWSE0009E: Internal
server error. No devices found [project worklight]
Here is the adapter code:
function submitBroadcastNotification( notificationText) {
var notification = {};
notification.message = {};
notification.message.alert = notificationText;
//notification.target = {};
//notification.target.tagNames = ['test'];
WL.Logger.debug("broadcast: " + notification.message.alert );
var delayTimeOut = **WL.Server.sendMessage**("PushNotificationsApp", notification);
WL.Logger.debug("Return value from WL.Server.sendMessage :"+ delayTimeOut);
return {
result : "Notification sent to all users"
};
}
Here is the PushBackendEmulator code:
public static void main(String [] args){
String serverUrl =
"http://208.124.245.78:9080/worklight";
String notificationText = "Hellofrombroadcastingnotifications";
String userId = "admin";
notificationText = notificationText.replace(" ", "%20");
Logger.debug("sending broadcast notification: " + notificationText);
URL url = new URL(serverUrl
+ "/invoke?
adapter=PushAdapter&procedure=submitBroadcastNotification¶meters=['" + userId + "','" + notificationText + "']");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setReadTimeout(10000);
connection.setDoOutput(true);
Logger.debug("Connected to server");
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = "";
String inputLine;
while ((inputLine = in.readLine()) != null)
response+= inputLine;
Logger.debug("response is:"+ response);
in.close();
Logger.debug("Server response :: " + response);
connection.disconnect();
Looking at your application from the PMR, it seems to me like you have mixed both event source-based notifications and broadcast notifications.
If you want to use Broadcast notifications, this means you cannot try imposing sending the notification to any specific userId, etc as it is not needed nor based on userIds.
By default, all devices are auto-subscribed to a tag called "push.ALL".
You can read more about broadcast notifications API methods in the IBM Worklight Knowledge Center.
This is a modified version of your application, tested in iOS and Android: https://www.dropbox.com/s/l2yk2pbvykrzfoh/broadcastNotificationsTest.zip?dl=0
Basically, I stripped away from it anything not related to broadcast notifications:
I removed the push securitytest from application-descriptor.xml
I removed any function from the adapter XML and JS files and main.js file that is related to event source-based notifications.
The end result is that after the app is loaded, you are right inside the application (no login).
I then right-clicked the adapter folder in Studio > invoke procedure, and selected the submitBroadcastNotification option to send the notification ("aaa").
In the device, a notification was received. Tapping it (if the app is closed) launches the application, which then triggers the WL.Client.Push.onMessage API in common\js\main.js to display alerts containing the payload and props of the received notification.
This was tested in both iOS and Android.
As the application was loading, I could see in LogCat and Xcode console the token registration.
To test this in iOS, you will need to update application-descriptor.xml with your own pushSender password and add your own apns-certificatae-sandbox.p12 file.
To test in Android, make sure you are have generated a browser key in the GCM console and are using it in application-descriptor.xml
For both, make sure that all requires ports and addresses and accessible in your network