Search code examples
restpush-notificationquickblox

QuickBlox REST API unable to get push notification subscription list


I've been using QuickBlox to send push notifications to our app on iOS and Android. I'm using Marmalade C++ SDK to develop the app. I have a problem getting the active push notification subscriptions for the logged in user.

I have checked from the QB admin panel that the user I'm using has active push notification subscriptions, but the request GET api.quickblox.com/subscriptions.json returns 404 not found.

The documentation for the API method Retrieve subscriptions states that there are no parameters that need to be passed with the request. The only information it needs is the QB-Token passed in a header. The token indirectly specifies the logged in user so it makes sense that is all it needs.

However, the description for the method is

Retrieve subscriptions for the device which is specified in the authorization token.

But that cannot be entirely true, because there is no way of knowing which device is making the request. I have assumed it means to retrieve subscriptions for the user.

In our app, the retrieve subscriptions request is performed just after logging in a user. I have confirmed that the login is successful and other API methods function normally.

After I get the 404, I try to create a new subscription for the current device for the user. If a subscriptions already exists for the device, the POST api.quickblox.com/subscriptions.json returns 201 for success, but the response body is just []. If there previously was no subscription for the device, the request returns 201, but the response body contains the created subscription's information.

I am able to create and delete notification events just fine and they are delivered to devices just fine. My problem is that I cannot easily confirm if the device has a valid subscription and I can't know what that subscription's ID is so I could delete it when the user logs out.


Solution

  • OK, I have managed to solve this issue, I too was confused by the documentation and it doesn't clearly explain what it means by

    Retrieve subscriptions for the device which is specified in the authorization token.

    I was also having an issue getting the user to sign up for subscriptions due to the vague wording of this documentation.

    In order to get an authorization token for Quickblox (for session or user session) you must have previously generated a HMAC SHA1 signature using the parameters described in the documentation:

    • application_id (API Application Identifier)
    • auth_key (AuthenticationKey)
    • timestamp (Unix Timestamp)
    • nonce (Unix Timestamp)
    • user[login]
    • user[password]
    • signature (HMAC SHA1, described below)

    Using these parameters and their values you should have created a string that looks like this:

    'application_id=22&auth_key=wJHd4cQSxpQGWx5&nonce=33432&timestamp=1326966962&user[login]=test@test.com&user[password]=test123'

    And then HMAC SHA1 this value, using your app secret as the HMAC secret, to get the signature for the request, e.g. C#

            using (HMACSHA1 hmac = new HMACSHA1(Encoding.ASCII.GetBytes(secret)))
            {
                hmac.Initialize();
                byte[] buffer = Encoding.ASCII.GetBytes(value);
                return BitConverter.ToString(hmac.ComputeHash(buffer)).Replace("-", "").ToLower();
            }
    

    Once you have this signature, you can then send the request to Quickblox to get an authorization token, for this example it is a token for a user session.

    You will need to send all of the parameters used to generate the signature, including the generated signature, in the body of the request, and POST it to the endpoint /session.json

    E.g. POST to /session.json

    {  
       "application_id":"2",
       "auth_key":"DtF9cZPqTF8Wy9Q",
       "timestamp":"1333630392",
       "nonce":"1236221330",
       "user":
       {
         login: "test@test.com",
         password: "test123"
       },
       "signature":"eb0ec2d8c8184a3e62b41da2afb6e8d690577fa4"
    }
    

    The response you get should have the Authorization token we need for user session requests.

    To solve your issue

    As you mention, this token does not work for retrieving user subscriptions, and returns a not found, despite the subscription for push notifications already existing and being linked to the user.

    The reason this happens is because the user has a 1:M relationship with devices, and Quickblox doesn't return all subscriptions, only subscriptions pertaining to a specific device from which the requests originates, but you have to tell it this.

    The missing element we had was adding the device parameters to the authorization token, which is very badly described, if at all, in the documentation.

    In order to make it work correctly, we need to add device[udid] and device[platform] to the authorization request. This identifies both the user, and the specific device they are using to Quickblox.

    To do this, do the exact same as described above but the value you HMAC SHA1 should now look like this

    'application_id=22&auth_key=wJHd4cQSxpQGWx5&device[platform]=android&device[udid]=2374682h23780239j&nonce=33432&timestamp=1326966962&user[login]=test@test.com&user[password]=test123'

    Please be aware if you put the keys in a different order, you will get an 'unexpected signature' error, device[platform] must come after auth_key etc...

    Use this string to generate your signature, and then send it using a similar request as above:

    E.g. POST to /session.json

    {  
       "application_id":"2",
       "auth_key":"DtF9cZPqTF8Wy9Q",
       "timestamp":"1333630392",
       "nonce":"1236221330",
       "user":
       {
         login:"test@test.com",
         password:"test123"
       },
       "device":
       {
         "platform":"android",
         "udid":"2374682h23780239j"
       }
       "signature":"5t4d2d8c81848b6c4s41da2afb6e8d690889bc4"
    }
    

    The token you get back from Quickblox should then be used as the QB-Token header value when requesting subscriptions using: GET /subscriptions.json

    After raising tickets and scouring the internet I managed to find this solution by stumbling onto this code and studying it for a short while.

    Sourcecode for Blackberry PushAuth using Quickblox

    I hope this helps others who are stuck with this as I assume Aleksi Grön has solved this issue after 2 months.