Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to query classes in cloud functions when we define multiple apps. #5988

Closed
rameshkec85 opened this issue Aug 28, 2019 · 5 comments
Closed

Comments

@rameshkec85
Copy link

rameshkec85 commented Aug 28, 2019

Issue Description

I have created 2 apps using parse-server and parse-dashboard. Both the apps have different mongodb uris.

var api_app2 = new ParseServer({
  databaseURI: process.env.databaseURI, // Connection string for your MongoDB database
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + "/cloud/main.js",
  appId: 'app2',
  masterKey: process.env.masterKey,
  serverURL: `${process.env.serverUrl}/parse`,
});
app.use('/parse/app2', api_app2);

var cwapp = new ParseServer({
  databaseURI: "mongodb://......../cw-app",
  cloud: process.env.CLOUD_CODE_MAIN || __dirname + "/cloud/cwapp/main.js",
  appId: 'cwapp',
  masterKey: process.env.masterKey,
  serverURL: `${process.env.serverUrl}/parse`,
});
app.use('/parse/cwapp', cwapp);

I have verified in API Console, which returns the results of the class successfully.

curl -X GET \
-H "X-Parse-Application-Id: cwapp" \
-H "X-Parse-Master-Key: MASTER_KEY" \
http://localhost:1337/parse/cwapp/classes/TestDB

But I am trying to write cloud function for one app ('cwapp').

  1. Working fine while invoking this cloud function using sample provided by the parse docs:
Parse.Cloud.define('Hello', function(req,res){
    return {"success":"200"};
})

Curl command :

curl -X POST \
-H "X-Parse-Application-Id: cwapp" \
-H "X-Parse-Master-Key: MASTER_KEY" \
http://localhost:1337/parse/cwapp/functions/Hello

But while i am trying to query the class within the cloud function it throws an error.

Here is my cloud function code in the same file (cloud/cwapp/main.js)

Parse.Cloud.define('getTestData', async (req,res) => {
    try{
        let itemQuery = new Parse.Query("TestDB");
        const result = await itemQuery.find({useMasterKey:true});
        return result;
    } catch(error){
        console.log(error);
        return error;
    }
})
curl -X POST \
-H "X-Parse-Application-Id: cwapp" \
-H "X-Parse-Master-Key: MASTER_KEY" \
http://localhost:1337/parse/cwapp/functions/getTestData

{
    "result": {
        "message": "Received an error with invalid JSON from Parse: <!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot POST /parse/classes/TestDB</pre>\n</body>\n</html>\n",
        "code": 107
    }
}

I am suspecting cloud functions unable to access its own database which is configured for app (cwapp) while i am using cloud functions.

Steps to reproduce

  1. Create multiple apps(minimum of 2)
  2. Name one of the app cwapp
  3. Create one class name called as TestDB in cwapp
  4. Write cloud functions for cwapp of the app
  5. Try to access the class TestDB to read the data within cloud functions
  6. will get an error : Cannot POST /parse/classes/TestDB

Expected Results

Cloud function should return the results of the TestDB classes.

Actual Outcome

Getting an error :

{
    "result": {
        "message": "Received an error with invalid JSON from Parse: <!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<title>Error</title>\n</head>\n<body>\n<pre>Cannot POST /parse/classes/TestDB</pre>\n</body>\n</html>\n",
        "code": 107
    }
}

Environment Setup

  • Server

    • parse-server version (Be specific! Don't say 'latest'.) : ^3.7.2
    • Operating System: Mac
    • Hardware:
    • Localhost or remote server? : Local
  • Database

    • MongoDB version: 3.2.0
    • Storage engine: mLab
    • Hardware: [FILL THIS OUT]
    • Localhost or remote server? mLab

Logs/Trace

info: Ran cloud function getTestData for user undefined with:
Input: {}
Result: {"message":"Received an error with invalid JSON from Parse: \n<html lang="en">\n\n<meta charset="utf-8">\n<title>Error</title>\n\n\n

Cannot POST /parse/classes/TestDB
\n\n\n","code":107} {"functionName":"getTestData","params":{}}

@davimacedo
Copy link
Member

I think the problem happens because the second app is mounted in a nested route. Try to mount the second app in another route, maybe: app.use('/parseapp2', api_app2);

@rameshkec85
Copy link
Author

Hi @davimacedo , thanks for the response. I have tried as you mentioned, but no luck.. :(

tried this one also :

app.use('/parse/cwapp', cwapp);

@davimacedo
Copy link
Member

Can you please share your most updated code including the lines that you are using to initiate Parse Server and the ones that you are mounting the apis to your Express.js app? I will try to simulate the problem.

@rameshkec85
Copy link
Author

rameshkec85 commented Aug 29, 2019

Hi @davimacedo, Please find the logs what i have tried and also attached app.js

cloud function POST method refers to /cwapp/functions/getTestDB, But

Query in cloud function is referring to /app1/classes instead of /cwapp/classes
GET /app1/classes/TestDB 200 5879.092 ms - 14

POST /cwapp/functions/getTestDB 400 1.865 ms - 54
GET /app1/classes/TestDB 200 5879.092 ms - 14
info: Ran cloud function getTestData for user undefined with:
  Input: {}
  Result: [] {"functionName":"getTestData","params":{}}
POST /cwapp/functions/getTestData 200 5887.392 ms - 13

I have added app.js content in the below attachment. i have also added mlab url for reference too.

Only cwapp is pointing to mLab url, rest of the apps to local mongodb url

.env file :

databaseURI=mongodb://localhost/test
appId=APP_ID
masterKey=MASTER_KEY
javascriptKey=javascriptKey
restAPIKey=REST_API_KEY
serverUrl=http://localhost:1337
appName=MyDemo
masterUsername=masterUsername
masterPassword=masterPassword

package.json :

{
  "name": "parseserverdashboard",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "cloud": "^2.0.2",
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "dotenv": "^8.0.0",
    "express": "~4.16.1",
    "http-errors": "~1.6.3",
    "jade": "~1.11.0",
    "morgan": "~1.9.1",
    "parse-dashboard": "^1.4.3",
    "parse-server": "^3.7.2"
  }
}

Cloud Function: cloud/cwapp/main.js

Parse.Cloud.define('getTestData', async (req,res) => {
    try{
        let itemQuery = new Parse.Query("TestDB");
        const result = await itemQuery.find({useMasterKey:true});
        return result;
    } catch(error){
        console.log(error);
        return error;
    }
});

Note: if i am changing the order from
app.use('/parse/cwapp', cwapp);
app.use('/parse/app1', app1);

to
app.use('/parse/app1', app1);
app.use('/parse/cwapp', cwapp);

works fine....but app1 got effected this time.

@davimacedo
Copy link
Member

Thanks for sending the detailed information. I've just gone through your code and I've figured out that it will actually not work.

Since the apps are instantiated under the same Node.js process, they are sharing the same Parse JS SDK. But the JS SDK was designed to connect to a single server URL as you can see here. The Parse.serverURL is a static member that is used in the Parse initialization here. It means that, at each initialization, the server url will be overridden. So all your cloud code functions, when using the Parse SDK, will actually connect to the last Parse Server you instantiated.

So here it goes your options:

Since this issue is actually the same of https://github.com/parse-community/parse-server/blob/master/src/ParseServer.js#L66, I will close this one and we can keep following up the other.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants