What is causing this BadDeviceToken response from APNs?

I am trying to migrate to the new APNs Provider API.

Here is how I've been registering for push notifications:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions

{

    //-- Set Notification
    if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])

    {

        // iOS 8 Notifications: Registering for notifications and types
        [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];

        [application registerForRemoteNotifications];

    }

    else

    {

        // iOS < 8 Notifications
        _storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:

         (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];

    }

    _storyBoard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];

    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:

     (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert)];

    if (launchOptions != nil)

    {

        NSDictionary* dictionary = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

        if (dictionary != nil)

        {

            NSLog(@"Launched from push notification: %@", dictionary);

            /*[self addMessageFromRemoteNotification:dictionary updateUI:NO];*/

        }

    } 

    return YES;

}

Within the last week, I have been using the following terminal command from Sending Push Notifications Using Command-Line Tools to successfully send a test push notification to a testing device.

curl -v --header 'apns-topic: com.domain.appname' --header apns-push-type: alert --cert aps.cer --cert-type DER --key PushChatKey.pem --key-type PEM --data '{"aps":{"alert":"Test"}}' --http2  https://api.sandbox.push.apple.com/3/device/258ecf658e25256c8f06ddb1138d5d536ba0e760a96ebd12d3b1dbe112857c58

Recently after creating provisioning profile and adding it to Xcode, the app no longer prints the device token in the debug window.

After removing the provisioning profile from my Apple Developer account under profiles, I tried using a backed up version of the app which still prints a device token to the debugger window.

When I copy the device token and enter it into the terminal command to send another test push notification, the terminal output is a 400 status code : {"reason":"BadDeviceToken"}* Closing connection 1


curl -v --header 'apns-topic: com.domain.appname' --header apns-push-type: alert --cert aps.cer --cert-type DER --key PushChatKey.pem --key-type PEM --data '{"aps":{"alert":"Hello From Faunna"}}' --http2  https://api.sandbox.push.apple.com/3/device/a146d82d4acea02c9ef6de5838174292d0e2cd18a40be17fb79334c5003a0058



* Could not resolve host: alert



* Closing connection 0



curl: (6) Could not resolve host: alert



*   Trying 17.188.138.73...



* TCP_NODELAY set



* Connected to api.sandbox.push.apple.com (17.188.138.73) port 443 (#1)



* ALPN, offering h2



* ALPN, offering http/1.1



Enter PEM pass phrase:



* successfully set certificate verify locations:



*   CAfile: /etc/ssl/cert.pem



  CApath: none



* TLSv1.2 (OUT), TLS handshake, Client hello (1):



* TLSv1.2 (IN), TLS handshake, Server hello (2):



* TLSv1.2 (IN), TLS handshake, Certificate (11):



* TLSv1.2 (IN), TLS handshake, Server key exchange (12):



* TLSv1.2 (IN), TLS handshake, Request CERT (13):



* TLSv1.2 (IN), TLS handshake, Server finished (14):



* TLSv1.2 (OUT), TLS handshake, Certificate (11):



* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):



* TLSv1.2 (OUT), TLS handshake, CERT verify (15):



* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):



* TLSv1.2 (OUT), TLS handshake, Finished (20):



* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):



* TLSv1.2 (IN), TLS handshake, Finished (20):



* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384



* ALPN, server accepted to use h2



* Server certificate:



*  subject: CN=api.development.push.apple.com; OU=management:idms.group.533599; O=Apple Inc.; ST=California; C=US



*  start date: Feb  8 21:41:22 2021 GMT



*  expire date: Mar 10 21:41:22 2022 GMT



*  subjectAltName: host "api.sandbox.push.apple.com" matched cert's "api.sandbox.push.apple.com"



*  issuer: CN=Apple Public Server RSA CA 12 - G1; O=Apple Inc.; ST=California; C=US



*  SSL certificate verify ok.



* Using HTTP2, server supports multi-use



* Connection state changed (HTTP/2 confirmed)



* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0



* Using Stream ID: 1 (easy handle 0x7fbd4700aa00)



> POST /3/device/a146d82d4acea02c9ef6de5838174292d0e2cd18a40be17fb79334c5003a0058 HTTP/2



> Host: api.sandbox.push.apple.com



> User-Agent: curl/7.64.1



> Accept: */*



> apns-topic: com.faunna.PushChat



> Content-Length: 37



> Content-Type: application/x-www-form-urlencoded



> 



* Connection state changed (MAX_CONCURRENT_STREAMS == 1000)!



* We are completely uploaded and fine



< HTTP/2 400 



< apns-id: 8DE6AA75-8E41-E95E-1FAF-51D93A8B3200



< 



* Connection #1 to host api.sandbox.push.apple.com left intact



{"reason":"BadDeviceToken"}* Closing connection 1



What is causing the bad device token output in this set up? And how should I be registering for remote notifications from this point forward?

Accepted Reply

The token 'a146d82d4acea02c9ef6de5838174292d0e2cd18a40be17fb79334c5003a0058' is a Production token, but you are using it with the Sandbox environment.

Development or Production tokens can only be used in the environments they belong in. The environment a token belongs to is determined by the "aps-environment" entitlement. By default, Xcode will set this to 'development' for debug builds, and 'production' for release builds. So, if you install the app via Xcode, you will get a development token, and if the app is installed from the App Store, you will get a production token.

You will need to make sure that the push is being sent on the environment the token belongs in. You are getting a production token because the baked up version of the app you are using must either be a Release version, or manually have the aps-environment set to Production.

  • Thank you. The APS entitlement was set to development.

  • I was banging my head but this was the solution. Thank you

Add a Comment

Replies

The token 'a146d82d4acea02c9ef6de5838174292d0e2cd18a40be17fb79334c5003a0058' is a Production token, but you are using it with the Sandbox environment.

Development or Production tokens can only be used in the environments they belong in. The environment a token belongs to is determined by the "aps-environment" entitlement. By default, Xcode will set this to 'development' for debug builds, and 'production' for release builds. So, if you install the app via Xcode, you will get a development token, and if the app is installed from the App Store, you will get a production token.

You will need to make sure that the push is being sent on the environment the token belongs in. You are getting a production token because the baked up version of the app you are using must either be a Release version, or manually have the aps-environment set to Production.

  • Thank you. The APS entitlement was set to development.

  • I was banging my head but this was the solution. Thank you

Add a Comment

I have the same problem for one of my projects. aps-environment is set to development but it receives a production token. Anything else could be triggering this?

Anyone?

I've had the same issue, but the accepted answer helped me figure out the solution. If you build you app for simulator or a physical device via xcode for development, the device will be treated as using a sandbox, so a "sandbox" token will be registered. So you either have to use a sandbox key on your server or you have to archive your app as for "production". that's the issue i was having. I've had only production key, so i've archived my app and distributed it via TestFlight and the issue was gone. Perhaps this could help somebody in the future