Push Notifications not received

I am trying to configure a Docker-based deployment of Parse server with push notifications.

The server is up and running, including the push notification settings as environment variables. The .p12 used was the “Development SSL Certificate” associated to the Push Notification settings of my in-development iOS app (the .cer file was downloaded, double-clicked to import to my Keychain, then exported as .p12)

This environment variable is as follows:
- PARSE_SERVER_PUSH={"ios":{"pfx":"/opt/bitnami/parse/pushcert/Parse-App-Name.APS_Dev.Export.p12","topic":"com.domain.Parse-App-Name","production":false}}

I have followed guides at various locations:

From this configuration, I have run the iOS app a couple times, so it has asked for push notification permission and completed the registration / installation of the device into Parse. If I go to the Parse Dashboard, and attempt to Send New Push I can see my single device / audience.

However, using the Dashboard to send a message, it is never received. Selecting this previously sent message, shows:

Separately, I downloaded a Mac app, APNS-Tool, from the Mac App Store that assists with development. I can send direct push notifications by providing the device’s token (obtained from the app running), the development certificate (the same source certificate of my Parse server’s .p12 file), and these are received. This tells me that the setup I have should work, but doesn’t…

Anyone able to assist?

Some additional info, as I saw some material on Apple’s site for troubleshooting APNs.

This is deployed on a single Docker host with Parse running against my local network’s server hostname. When I run my test iOS app, the AppDelegate is set to use this internal URL name, such as:
http://localserver.home.local:1337/parse

I have multiple websites / services running from port 80 & 443 to allow web hosting running from the same home server, with other Docker containers handling reverse-proxying and LetsEncrypt SSL. So my Parse container doesn’t have an internet routable path via port 443 as mentioned in the above document. I would have the same issue with the other port 2195.

I have not seen any reference to this in the guides / tutorials for this, and my container is able to reach outbound to the internet. Inbound is restricted.

Following more documentation, from my Docker host, running the test push notification curl command:

curl -X POST \
  -H "X-Parse-Application-Id: myappID" \
  -H "X-Parse-Master-Key: mymasterKey" \
  -H "Content-Type: application/json" \
  -d '{
        "where": {
          "deviceType": {
            "$in": [
              "ios"
            ]
          }
        },
        "data": {
          "title": "The Shining",
          "alert": "All work and no play makes Jack a dull boy.",
          "content-available": 1,
          "push_type": "background"
        }
      }'\   http://server.home.local/parse/push

(Note, also tried “push-type”)

I receive this in the terminal:

<html>
<head><title>503 Service Temporarily Unavailable</title></head>
<body>
<center><h1>503 Service Temporarily Unavailable</h1></center>
<hr><center>nginx/1.17.6</center>
</body>
</html>

So I have been able to progress the response / error below:

In the CURL command, the connection string example didn’t include the port number, so I also omitted it. Adding in the custom port number I am using, 1338 in my case, this command:

curl -X POST \
>   -H "X-Parse-Application-Id: myappID" \
>   -H "X-Parse-Master-Key: mymasterKey" \
>   -H "Content-Type: application/json" \
>   -d '{
>         "where": {
>           "deviceType": {
>             "$in": [
>               "ios"
>             ]
>           }
>         },
>         "data": {
>           "title": "The Shining",
>           "alert": "All work and no play makes Jack a dull boy.",
>           "push-type": "background"
>         }
>       }'\
>          http://server.home.local:1338/parse/push

Returns:
{"result":true}

And if I return to the Dashboard, under the Push menu > Past Pushes, I can see all these requests.

However, NONE are actually received on the device!

I have tried some variations in the data JSON object, including extra parameters that seem to be now be required iOS 13 devices, namely:

  • push-type / push_type / apns-push-type

  • content-available

I think I have tried all combinations, but still no received notification…

Not sure what or where to look now…
What tests and/or logs are available between my Parse server and Apple’s APNS servers?

Have you added the client code to save the installations? Can you share some of the installations that should receive the push?

I am now also learning how to properly send push with Parse and I found similar issue. I am saving Installation and when have following testing code in the cloud trigger, the device receives the push:

Parse.Cloud.afterSave("Inbox", async ({object, log}) => {
    const rid = object.get("rid");
    if (object.existed() || !rid) {
        //proceed only if new object and recipient id is defined        
        return;
    }
    const query = new Parse.Query(Parse.Installation);
    query.equalTo("userId", rid);

    return Parse.Push.send({
        where: query,
        data: { 
            alert: "Inbox"/*, 
            push_type: "background" */
        }
    }, { useMasterKey: true }).then(function() {
        // Push sent!
    }, function(error) {
        log.error(`Error sending push notification on new Inbox ${error.code}: ${error.message}`);
    });
    
});

but when I uncomment that push_type: "background", the notification is not received. I mean not even in the application delegate as it should be silent one… In the documentation I have not found any example for iOs silent notification with some data payload.

When I tried to add custom field, it was received:

Parse.Push.send({
        where: query,
        data: { 
            alert: "Inbox",
            customField: 12/*, 
            push_type: "background" */
        }
    }, { useMasterKey: true }).then(function() {
        // Push sent!
    }, function(error) {
        log.error(`Error sending push notification on new Inbox ${error.code}: ${error.message}`);
    });

Xcode Debug:

userInfo: [AnyHashable(“customField”): 12, AnyHashable(“aps”): {alert = Inbox;}]

unfortunately with the push_type: "background" uncommented, the notification was not received by client

Would you mind to share the client code that you are using to receive the push?

I am so far only printing userInfo in the delegate function:

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

After further investigation I noticed that following variation is being received:

Parse.Push.send({
        where: query,
        data: { 
            "content-available": 1,
            "push_type": "background",
            "customField": 12
        }
    }, { useMasterKey: true })

userInfo: [AnyHashable(“push_type”): background, AnyHashable(“customField”): 12, AnyHashable(“aps”): {
"content-available" = 1;
}]

Unfortunately it is also not waking the app and I can’t figure out if it is the xcode side or push side. If anyone would have experience on that, I would greatly appreciate the help. Thank you

Did you try it out on a physical device? Unless something has changed in Xcode that I’m unaware of, the iOS simulator isn’t allowed to receive remote push notifications.

Update: there have been some changes. Do you receive notifications when you follow the article: Testing push notifications on the iOS simulator - SwiftLee

Yes, I am testing it on a physical device, otherwise there is also no notification received in the simulator foreground. Reading on the internet I found that:

  • silent notification are throttled and there should not be more than 3/hour
  • silent notifications are not received when user terminated the app in app switcher

Therefore it is not suitable for my needs and I am trying to implement UNNotificationServiceExtension instead.