2

I am trying to post votes to 'fivestar' ratings on my D7 site, through my iOS app (xcode7, swift2). My iOS swift API to post a vote to the votingapi REST services post gives me a 200 status ok, and no errors. But my Drupal site/database does not register/save the vote. When I use the URL directed in Drupal services definitions I get status 500 (internal server error) and this log message (on 2 sites I'm testing on);

  ServicesException: Missing entity ID for vote tag in services_error() (line 366 of /home/example/public_html/example.com/sites/all/modules/services/includes/servi‌​ces.runtime.inc)

So I am wondering which is the correct URL and if I should use the URL without the node then how to fix this 'entity_id' error, if that is the problem? U

see screenshot of database showing vote example, entered directly on d7 site, saved correctly. It does not register my second vote through the API.

Here is my code:

    // submit vote

    let voteEndpoint: String = "https://www.example.com/node/7291/ios1/votingapi/set_votes"
    let newVote = ["votes":["value":40, "uid":235, "vote_id":75000, "timestamp":146882901,  "vote_source":"70.36.223.173", "entity_id":7291, "entity_type":"node", "tag":"vote", "value_type":"percent"]]
    Alamofire.request(.POST, voteEndpoint, parameters: newVote, encoding: .JSON)
        .response { request, response, data, error in
            print(request)
            print (response)
            print (error)
    }

After repeating the URL as given above, the console returns:

 { status code: 200, headers {
    "Cache-Control" = "no-cache, must-revalidate";
    Connection = "Keep-Alive";
    "Content-Language" = en;
    "Content-Type" = "text/html; charset=utf-8";
    Date = "Tue, 19 Jul 2016 00:09:53 GMT";
    Expires = "Sun, 19 Nov 1978 05:00:00 GMT";
    "Keep-Alive" = "timeout=10, max=200";
    Link = "</node/7291>; rel=\"shortlink\",</Never-Return-to-Venice-chapter5>; rel=\"canonical\"";
    Server = Apache;
    "Set-Cookie" = "DRUPAL_UID=0; expires=Mon, 18-Jul-2016 00:09:53 GMT; Max-Age=-86401; path=/; domain=.example.com; secure, DRUPAL_UID=-1; expires=Thu, 11-Aug-2016 03:43:13 GMT; Max-Age=1999999; path=/; domain=.example.com; secure";
    "Transfer-Encoding" = Identity;
    "X-Content-Type-Options" = nosniff;
    "X-Frame-Options" = SAMEORIGIN;
    "X-Generator" = "Drupal 7 (http://drupal.org)";
    "X-Powered-By" = "PHP/5.6.9"; } }) nil
  • The drupal system and voting modules are up to date

  • I have cleared cache and run cron.

  • I have tried testing it with a new services endpoint

  • I have no status report errors reporting any problems with the voting modules.

  • There are no error messages in the Drupal log

  • The anonymous permissions are set to allow voting.

  • voting is saving normally on direct votes on the drupal site.

  • There is no authentication on the drupal services, and voting api is set.

  • Developers have confirmed my swift code looks correct

  • according to this drupalcontrib webpage information, my votingapi parameters are correct, yes? see drupalcontrib.org/api/drupal/contributions%21votingapi%21votingapi.module/class/VotingApi_Vote/7

  • my database does not mention 'votes' but for the array it does confirms these parameters I have used are the correct parameters.

  • web surfing confirms these are correct values for the parameters, with the only mandatory parameters as 'value', 'uid', 'entity_id', 'entity_type'. I have tried using only those parameters, same result.

I have tried a multitude of variations, but all of them give status 200 but no vote in my drupal database. I tried rate module (and its custom tags instead of 'vote') but get the same result. I tried without .json at the URL. I tried other possible variations of entity_type eg 'article' instead of 'node' etc. I tried without the node/xxxx in the URL. I tried without 'vote' (as per other modules), 'criteria' instead of 'votes'.

I am using the node ID for the "entity_id". Is that correct?

Any ideas?

IS it something with this: - Drupal services definitions lists: SET_VOTES Set votes for an entity POST : https://www.example.com/ios1/votingapi/set_votes

The rest service endpoint is ios1. When I include node/7291 in the URL (before ios1), hooray it returns status 200. BUT it doesn't register the vote in the database. When I use the URL (without the node) as per the Services Definitions, I get status 500 and the 'services exception: Missing Entity ID' error (above).

The site's services definitions -as per this screenshot- confirms the parameters as an 'array' for 'votes'. And an array for 'criteria' as not mandatory. Please see attached. [see screenshot: drupal services defintions][1

10
  • What's the path to your endpoint? Do you have the session authentication box checked on your Service endpoint? Commented Jul 19, 2016 at 2:02
  • Hi Tyler, thank you so much, I've followed your posts and tutorials online for a while (which are great) and was thinking you'd be the perfect person to look at this. The path to the endpoint is ios1. I do not have any session authentication checked (as I thought that would keep it simpler for me to set up first. I can see modules to add for http authentication but I'm a new coder, not sure what code to add to authenticate the REST call?
    – Dimitri T
    Commented Jul 19, 2016 at 2:12
  • Those 2 errors were arising on all APIs. So I restored to a backup which works with other API calls. On this & another newer site I have, if I include the node in the URL I get status200, no log messages, but no vote registered. If I post to example.com/ios1/votingapi/set_votes then I get a status500 on my console , no vote registered, and although I have included entity_id in the parameters, it logs: ServicesException: Missing entity ID for vote tag in services_error() (line 366 of /home/humanfpt/public_html/example.com/sites/all/modules/services/includes/services.runtime.inc) Thx for ideas?
    – Dimitri T
    Commented Jul 19, 2016 at 5:09
  • I am using the nodeID as the 'entity_id' (reading it from the URL on node edit). I presume that is correct? If not, then that might be the problem here, and the Q would be how do I find the entity_id?
    – Dimitri T
    Commented Jul 19, 2016 at 5:28
  • 1
    So relieved to have an answer!! It is now passing the API, with Basic Auth headers and also extra brackets around the parameters, as such: let newVote = ["votes":[["value":100,"uid":32,"entity_id":1,"entity_type":"node","tag":"vote","value_type":"percent"]]] Alamofire.request(.POST, voteEndpoint, parameters: newVote, encoding: .JSON)
    – Dimitri T
    Commented Jul 22, 2016 at 10:06

1 Answer 1

0

Solved: I added Basic Auth with a header of "Content-Type : application/json" and also an extra bracket around the array parameters.

This full code is passing votes successfully:

     // API request

    let user = "username"
    let password = "pass"
    let credentialData = "\(user):\(password)".dataUsingEncoding(NSUTF8StringEncoding)!
    let base64Credentials = credentialData.base64EncodedStringWithOptions([])
    let headers = ["Content-Type : application/json"]
    let voteEndpoint: String = "https://example.site/ios1/votingapi/set_votes.json"
    let newVote = ["votes":[["value":100,"uid":32,"entity_id":1,"entity_type":"node","tag":"vote","value_type":"percent"]]]
    Alamofire.request(.POST, voteEndpoint, parameters: newVote, encoding: .JSON)
         .response { request, response, data, error in
            debugPrint(response)
            print(request)
            print (response)
            print (error)
    }


}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.