Support Topics Documentation Slack YouTube Blog

push notification api to all devices not all getting delivered


(mike turner) #1

Hi Guys

I have been using the push notification api (javascript) to send push notifications to selected devices successfully.

We tried a push today to all devices, but it seems to be only partly successful. I know at least once device got the notification, but some did not. I did not receive it on my device and that has been working perfectly when sending tests to that one particular device when using the api to send to a selected device (s) only.

So as this seems to be a difficult thing to debug as I don’t think you can trace which notifications are delivered or not, is there anything which is likely to be stopping this working. Like can it hit a problem along the way and then stop sending push notifications to subsequent devices etc. etc or have I plain and simple missed something obvious! As I don’t know how many devices got the notification I can’t really try again on this particular push notification for fear of annoying those users who actually got it!

I only have 66 devices registered, so its not like a major push volume.

Am I wrong in the code?, although it is identical to the code which is working to sending out to selected devices (minus the delivery options). Is there anything else you can think of , or any mechanisms to debug what the problem is? It has been 2 hours and I am guessing even if it was in a queue it would have been delivered by now. (The one which worked got delivered straight away)

The code seems straightforward:

var publishOptions = new PublishOptions();
publishOptions.publisherId =“XXX”;

//for android messages to work we need to set these headers
publishOptions.headers = {“android-content-text”:messageShort, “android-content-title”:messageTitle, “android-ticker-text”:messageLong};

var channel = “default”;

//publish to everyone - use this - no delivery options necessary.
var response = Backendless.Messaging.publish( channel, messageLong, publishOptions);


(Sergey Chupov) #2

Hi Mike,

We do send notifications in a queue (one by one), so there might be a delay, and also there’s a slight possibility that if at some moment something goes totally wrong, the subsequent messages won’t be sent. I get your case, and will be creating a task to improve the possible error handling.

Though, it also depends on whether you observer the same result constantly. I mean, if the messages are not received only occasionally, then this might not be the case. Have you tried multiple times to prove that every time some messages are lost? This would help us narrow down the number of possible solutions.

As to the code, it is pretty straightforward, so you don’t need any changes there.


(mike turner) #3

Thanks Sergey

It was the first time we have done a push to all registered devices. As it was to ‘live’ customers we didn’t want to repeat the process for fear of some customers getting the message twice and getting irritated if you see what I mean.

We will run another push in the future so can observe if the same pattern happens then.

Thanks, and let me know when you have improved error handling and I will test that out in the next push.

Mike


(mike turner) #4

Hi Sergey. I wondered if you had managed to do anything to improve the error handling?

On a wider picture it would be really helpful to have some kind of feedback on the delivery or not of the messages. I know this seems to be difficult, but I note some more dedicated push systems seem to offer some kind of feedback on the delivery of notifcations (not sure how exactly how they do this or how accurate that actually is). I haven’t tried any of these yet as it would obviously be a lot neater to stick with backendless for notifications, but some sort of feedback or at least a warning of messages which weren’t delivered would be great if at all possible.

Mike


(Mark Piller) #5

Hi Mike,

The response object for the “publish” operation is an object which contains an ID of the published message (it is in the “messageId” property). it is possible to send a subsequent request to get the status of the message. If message delivery failed for any reason, the status you get back should contain the error message.

Here’s the API call to get message status:
https://backendless.com/docs/js/doc.html#messaging_get_message_status_2

Regards,
Mark


(mike turner) #6

Hi Mark,

Thanks for the info, interesting, I will try that now. I know some push notifications are getting delivered and some are not. Will this help to diagnose this situation as I presume that all the individual push notifications are just treated as one message?

Mike


(Mark Piller) #7

Hi Mike,

Yes, I believe it should give you the information you’re looking for. Please give it a try and let us know what you find out.

Regards,
Mark


(mike turner) #8

Hi Mark

I am getting a not a function error on this call (and the async call too).

var status = Backendless.Messaging.getMessageStatusSync( messageToCheck );

This is v3 app so I am referencing this sdk https://api.backendless.com/sdk/js/v3/backendless.js. Is this correct?

Mike


(Mark Piller) #9

Hi Mike,

In V3 that API is available only via REST, we added methods to the SDK only in version 4.

V3 get message status:
https://backendless.com/documentation/messaging/rest/messaging_get_message_status_2.htm


(mike turner) #10

Hi Mark

OK I have an update on this. As mentioned previously when I send test pushes to selected devices it seems to work perfectly, but when sending to all devices it seems to fail (or fails partially as a few users got a notification last time).

We did another push today to all devices, and this time I recorded the message ID so I could check the status and this is the error I get

MessageID: 0932FD19-BC50-FB50-FF37-D31074933900
status: failed

InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidParameters.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration.
InvalidRegistration

Can you help? Code same as last time (see thread above)


(Mark Piller) #11

Hi Mike,

Is the code still the same as you showed in the original post? If not, could you please post a snippet of code showing the code which sends a push notification that fails?

Regards,
Mark


(mike turner) #12

Yes, but here it is again

var publishOptions = new PublishOptions();
publishOptions.publisherId =“MGA”;

//for android messages to work we need to set these headers
publishOptions.headers = {“android-content-text”:messageShort, “android-content-title”:messageTitle, “android-ticker-text”:messageLong};

var channel = “default”;

//publish to everyone/BASIC PUSH NOTIFICATION - use this - no delivery options.
var response = Backendless.Messaging.publish( channel, messageLong, publishOptions);

console.log(response);
console.log(response.messageId);


(Mark Piller) #13

Thanks, Mike. What is the application id? Would it cause any harm if I send a test push notification to the “default” channel?


(mike turner) #14

Hi Mark, ah yes it would cause some harm I imagine as the app is using the default channel so I imagine everyone using the app would get your test message which wouldn’t be good. Can you use another channel so that if you send a test message it doesn’t go live to clients who are using the app? I’m sorry I don’t think I appreciated the value of channels when I created the app!


(Mark Piller) #15

sure, I can use another channel. Please let me know your app id and also register a device on your end with the “test” channel, so you can confirm if a push notification arrived or not. This is the one we will use for testing.


(mike turner) #16

OK I will get that setup.


(mike turner) #17

Mark just wondered is there a more private communication channel where I can send you the application ID?


(Mark Piller) #18

You’re welcome to send it to support@backendless.com or via direct message on Slack.


(mike turner) #19

Hi Mark

I’m not convinced I have set messaging up correctly in the actual app. For sure, it was working when I am sending to unique devices, but when I looked where you register the device with a channel I had set this up in the home page view controller and not the AppDelegate. Could this be a cause of the problem ? I have this setup in the AppDelegate

var backendless = Backendless.sharedInstance()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // Override point for customization after application launch.

    

 

    

   backendless?.initApp(APP_ID, secret:SECRET_KEY, version:VERSION_NUM)

  

    //Push Notification

    backendless?.messaging.registerForRemoteNotifications()



    

    

    return true

}











func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

   

    //Push Notification

    

    //Register this unique Device ID on backendless system so that we can send notifications.

    backendless?.messaging.didRegisterForRemoteNotifications(withDeviceToken: deviceToken)

   

   // Push Notification

   // print("DELEGATE DID REGISTER DEVICE FOR REMOTE NOTIFICATION")

   // print(deviceToken)

   // print(backendless.messagingService.currentDevice().deviceId)

}







func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {

    backendless?.messaging.didFailToRegisterForRemoteNotificationsWithError(error)

    print("DELEGATE DID FAIL REGISTER FOR REMOTE NOTIFICATION")

    //print(error)

}



func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {

    backendless?.messaging.didReceiveRemoteNotification(userInfo)

}



func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

    backendless?.messaging.didReceiveRemoteNotification(userInfo)

    completionHandler(.newData)

}





func applicationWillResignActive(_ application: UIApplication) {

    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.

    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.

}




func applicationDidEnterBackground(_ application: UIApplication) {

    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.

    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

}




func applicationWillEnterForeground(_ application: UIApplication) {

    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.

}




func applicationDidBecomeActive(_ application: UIApplication) {

    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.

}




func applicationWillTerminate(_ application: UIApplication) {

    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.

    // Saves changes in the application's managed object context before the application terminates.

    self.saveContext()

    

    backendless?.messaging.applicationWillTerminate()

}

and in the homepage view controller (viewDidLoad), this

    // backendless?.messaging.registerDevice(withChannels: ["default"])

    // Aug 17 2017 register test channel for testing

    

     backendless?.messaging.registerDevice(withChannels: ["test"])

I am thinking that should perhaps be in AppDelegate somewhere? Now that I have changed ‘default’ to ‘test’ the notifications which were working are no longer working! So need to solve that before you start testing… Can you confirm or otherwise if this setup looks correct?

Best, Mike


(Mark Piller) #20

Ouch, Mike, I am afraid I cannot digest that much code at once… Have you tried following the docs to make sure the code is in line with what we describe there?

Also, there is a code generator for push notifications which produces the code showing how to use the API.

Finally, do you plan to migrate to 4.x, where the docs and the platform are significantly improved?

Regards,
Mark