parse-community/parse-server

"Unable to connect to the Parse API" error thrown when trying to call a Cloud function with a Parse Query.

Closed this issue ยท 16 comments

I have defined a Cloud function in main.js as below:

Parse.Cloud.define('getAllCurrentObs', function(request, response) {
    Parse.Cloud.useMasterKey();

    var queryObs = new Parse.Query("GCUR_OBSERVATION");
    queryObs.ascending("createdAt");
    queryObs.equalTo("ObservationStatus", 0);
    queryObs.limit(1000);

    queryObs.find().then(function(results) {
        response.success(results.length);
    }, function(error) {
        response.error("Error: " + error.code + " " + error.message);
    });
});

While trying the POST cURL command line to call the function, the command line prompt showed the following error message:

curl -X POST -H "X-Parse-Application-Id: APP_ID" -H "X-Parse-Master-Key: MASTER_KEY" -H "Content-Type: application/json" -d "{}" https://{MY_APP_NAME}.herokuapp.com/parse/functions/getAllCurrentObs
{"code":141,"error":"Error: 100 XMLHttpRequest failed: \"Unable to connect to the Parse API\""}

The Heroku logs page showed:
2016-02-25T12:33:14.263956+00:00 heroku[router]: at=info method=POST path="/parse/functions/getAllCurrentObs" host={MY_APP_NAME}.herokuapp.com request_id=6af8cfa4-c935-4b52-a869-1d5dd47b93aa fwd="183.78.173.3" dyno=web.1 connect=0ms service=2764ms status=400 bytes=378

By the way, using cURL to post the default "hello" cloud function worked well.

Edit: I think the problem is any Parse Query made to a DB Class in a cloud function would fail.

Can you provide more context and detailed steps to reproduce the issue? That way it is easier to track down the root cause and it will be easier to provide help and a fix if necessary.

@grassland-curing-cfa did you set the serverURL in your parse server configuration?

@flovilmart No, I didn't. Where is the parse server configuration where the serverURL is set, in index.js?

I have the following index.js in my Parse-Server-Example folder.

// Example express application adding the parse-server module to expose Parse
// compatible API routes.

var express = require('express');
var cors = require('cors');
var ParseServer = require('parse-server').ParseServer;

var databaseUri = process.env.DATABASE_URI || process.env.MONGOLAB_URI;

if (!databaseUri) {
  console.log('DATABASE_URI not specified, falling back to localhost.');
}

var api = new ParseServer({
  databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
  appId: process.env.APP_ID || 'myAppId',
  restAPIKey: process.env.REST_API_KEY || '',
  javascriptKey: process.env.JAVASCRIPT_KEY || '',
  masterKey: process.env.MASTER_KEY || '' //Add your master key here. Keep it secret!
});
// Client-keys like the javascript key or the .NET key are not necessary with parse-server
// If you wish you require them, you can set them as options in the initialization above:
// javascriptKey, restAPIKey, dotNetKey, clientKey

var app = express();
app.use(cors());

// Serve the Parse API on the /parse URL prefix
var mountPath = process.env.PARSE_MOUNT || '/parse';
app.use(mountPath, api);

// Parse Server plays nicely with the rest of your web routes
app.get('/', function(req, res) {
  res.status(200).send('I dream of being a web site.');
});

var port = process.env.PORT || 1337;
app.listen(port, function() {
    console.log('parse-server-example running on port ' + port + '.');
});

Provide a serverURL option to the ParseServer call, something like:

var api = new ParseServer({
  databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
  appId: process.env.APP_ID || 'myAppId',
  restAPIKey: process.env.REST_API_KEY || '',
  javascriptKey: process.env.JAVASCRIPT_KEY || '',
  serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse',
  masterKey: process.env.MASTER_KEY || '' //Add your master key here. Keep it secret!
});

@gfosco Do I also need to set a Config Variable "SERVER_URL" in Heroku's Settings page? If so, and how?

I thought "PARSE_MOUNT" would do that... ...

  • APP_ID
  • JAVASCRIPT_KEY
    ... ...
  • PARSE_MOUNT: /parse
  • SERVER_URL: ???

Yes for heroku that would be your full heroku app address, like http://weee.herokuapp.com/parse

This helped!
https://{MY_APP}.herokuapp.com/parse
Thanks!

Since the problem fixed by adding SERVER_URL, I am still curious about why this was needed as it seems "PARSE_MOUNT: /parse" does the same thing. I have another Parse-server-exemple app deployed on Heroku but that one worked well without SERVER_URL set. Very weird.

The server url was added at some point, and was necessary for cloud code to know the right server to connect to when making requests back to the API. The mount variable is necessary for other reasons, just to know where on the domain it is hosted (creating file urls for example).

@gfosco I came across same issue, however, even after adding serverURL I am getting "XMLHttpRequest failed: "Unable to connect to the Parse API"". my parse-server is running on localhost.

 var api = new ParseServer({
  databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',
  appId: process.env.APP_ID,
  serverURL: 'http://localhost:1337/parse',
  masterKey: process.env.MASTER_KEY
});

Mongodb is hosted on MongoLab.

I am using self hosted parse-server and not able to use cloud functions since I have enabled HTTPS, if I revert it back to HTTP it works as expected.

Also he problem is only with those cloud function which have Parse.Query, if i create a function simply return "Hello" as response it works on both HTTP and HTTPS.

I am getting following error message when run a cloud function which have Parse.Query code.

{
"code": 141,
"error": "XMLHttpRequest failed: "Unable to connect to the Parse API"--100"
}

can anyone tell me how can I fix this?

I am having the same issue. Parse Query inside Cloud Code runs well with HTTP, however fails with "Unable to connect to the Parse API" when using HTTPS.

Any hints?

Just found the solution here:
#411

Just added:
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

in index.js, just before starting Parse Server:

var api = new ParseServer({...});

I was having the same issue and initially i though it was the cloud code that needed update. After a lot of troubleshooting I realised that the code was fine. Then I tried to see whether parse server was setup correctly. I am running it on IBM BlueMix (should be the same as heroku). The problem was the following

var parseConfig = { databaseURI: databaseUri, appId: process.env.APP_ID, masterKey: process.env.MASTER_KEY, cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js', serverURL: ((process.env.HTTPS) ? 'https' : 'http') + host + ':' + port + mountPath, };

The server url was resolving to "http0.0.0.0:61026/parse", which was incorrect. I updated it to include :// and the problem was resolved. The new configuration looked like the following:

var parseConfig = { databaseURI: databaseUri, appId: process.env.APP_ID, masterKey: process.env.MASTER_KEY, cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js', serverURL: ((process.env.HTTPS) ? 'https://' : 'http://') + host + ':' + port + mountPath, };

Such a simple mistake took me 4 hours to resolve.

my problem was i wasn't supply full cloud path
cloud: __dirname + '/cloud/main.js', // Absolute path to your Cloud Code