"Unable to connect to the Parse API" using Parse Server on Heroku - mongodb

I'm getting the error Failed to create new object, with error code: XMLHttpRequest failed: "Unable to connect to the Parse API" when i try to connect to Parse Server API. I deployed ParsePlatform/parse-server-example on Heroku. I can access to my app with a broswser with no problems.I get the error when trying to connect to Parse on Heroku with this code :
var $result=$('#results').html('Testing configuration.....');
Parse.initialize('<MY_APP_ID>', '<MY_JAVASRIPT_KEY>');
Parse.serverURL = '<MY_HEROKU_APP_NAME>.herokuapp.com/'
var ParseServerTest = Parse.Object.extend('ParseServerTest');
var _ParseServerTest = new ParseServerTest();
_ParseServerTest.set('key', 'value');
_ParseServerTest.save(null, {
success: function(_ParseServerTest) {
var txt = 'Yay, your server works! New object created with objectId: ' + _ParseServerTest.id;
$result.html('<div class="alert alert-success" role="alert">' + txt + '</div>');
},
error: function(_ParseServerTest, error) {
var txt = 'Bummer, Failed to create new object, with error code: ' + error.message;
$result.html('<div class="alert alert-danger" role="alert">' + txt + '</div>');
}
});
index.js
// 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 path = require('path');
var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_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',
masterKey: process.env.MASTER_KEY || '', //Add your master key here. Keep it secret!
serverURL: process.env.SERVER_URL || 'https://localhost:1337/parse', // Don't forget to change to https if needed
liveQuery: {
classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
}
});
// 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 static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
// 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 website. Please star the parse-server repo on GitHub!');
});
// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function(req, res) {
res.sendFile(path.join(__dirname, '/public/test.html'));
});
var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
console.log('parse-server-example running on port ' + port + '.');
});
// This will enable the Live Query real-time server
ParseServer.createLiveQueryServer(httpServer);
Heroku config :
I followed this post : How can I host my own Parse Server on Heroku using MongoDB? except i didn't use the "Deploy to Eroku" button, i deployed it manually.
Thank you for your help.

Finally I found a way.
I first created another user in my mongo db and change it in Heroku. Try to connect with the same js code code jsfiddle but didn't work...
Then I tried with an android client, this link helped me a lot http://www.robpercival.co.uk/parse-server-on-heroku/
StarterApplication.java
public class StarterApplication extends Application {
#Override
public void onCreate() {
super.onCreate();
// Enable Local Datastore.
Parse.enableLocalDatastore(this);
// Add your initialization code here
Parse.initialize(new Parse.Configuration.Builder(getApplicationContext())
.applicationId("BUTYcVjD7nFz4Le")
.clientKey("XgQaeDY8Bfvw2r8vKCW")
.server("https://xxxxx-xxxx-xxxxx.herokuapp.com/parse")
.build()
);
ParseUser.enableAutomaticUser();
ParseACL defaultACL = new ParseACL();
// Optionally enable public read access.
// defaultACL.setPublicReadAccess(true);
ParseACL.setDefaultACL(defaultACL, true);
}
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
ParseAnalytics.trackAppOpenedInBackground(getIntent());
ParseObject test = new ParseObject("Test");
test.put("username","pedro");
test.put("age",33);
test.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
Log.i("Parse", "Save Succeeded");
} else {
Log.e("Parse", "Save Failed");
}
}
});
}
I really don't know what was the problem with my first user, can't connect with it. I never could connect with the js code... but anyway my goal was to connect with Android client so...

Related

Loopback is not defined

Web server listening at: http://localhost:3000
Browse your REST API at http://localhost:3000/explorer
D:\PPL\Laundry\Front\api\node_modules\mysql\lib\protocol\Parser.js:80
throw err; // Rethrow non-MySQL errors
^
ReferenceError: loopback is not defined
Please add this line to fix this Error
var loopback = require('loopback');
'use strict';
var loopback = require('loopback');
var boot = require('loopback-boot');
var app = module.exports = loopback();
app.use(function(req, res, next) {
var allowedOrigins = [
'http://localhost',
'http://localhost:3000',
'http://127.0.0.1',
'http://127.0.0.1:3000',
];
var origin = req.headers.origin;
if (allowedOrigins.indexOf(origin) > -1) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Access-Control-Allow-Credentials', true);
next();
});
app.start = function() {
// start the web server
return app.listen(function() {
app.emit('started');
var baseUrl = app.get('url').replace(/\/$/, '');
console.log('Web server listening at: %s', baseUrl);
if (app.get('loopback-component-explorer')) {
var explorerPath = app.get('loopback-component-explorer').mountPath;
console.log('Browse your REST API at %s%s', baseUrl, explorerPath);
}
});
};
// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
boot(app, __dirname, function(err) {
if (err) throw err;
// start the server if `$ node server.js`
if (require.main === module)
app.start();
});
This could be a sample server.js. Please make sure that loopback module is referred.

Parse Server - Image files' path returns localhost

I have deployed 2 Ubuntu servers on Azure. First, I have installed the Parse Server and the second, I installed MongoDB. (I have also put a ready db there from my previous server via mongorestore)
Everything works fine! Both Parse Server and MongoDB server. They also communicate well. The thing is, when I run my iOS app, it brings all data correctly, except images. I print the URL of an image and here's what it returned: http://localhost:1337/parse/files/filename.jpeg
If I replace localhost with my server's ip, the image is being fetched nicely!
Here's what I have on my index.js:
var express = require('express');
var ParseServer = require('parse-server').ParseServer;
var ParseDashboard = require('parse-dashboard');
var allowInsecureHTTP = true;
var path = require('path');
var databaseUri = process.env.DATABASE_URI || process.env.MONGODB_URI;
if (!databaseUri) {
console.log('DATABASE_URI not specified, falling back to localhost.');
}
var api = new ParseServer({
databaseURI: databaseUri || 'mongodb://IP:27017/db',
cloud: './cloud/main.js',
appId: process.env.APP_ID || 'xxx',
masterKey: process.env.MASTER_KEY || 'xxx', //Add your master key here. Keep it secret!
fileKey: 'xxx',
serverURL: process.env.SERVER_URL || 'http://localhost:1337/parse', // Don't forget to change to https if needed
// Enable email verification
verifyUserEmails: false,
// The public URL of your app.
// This will appear in the link that is used to verify email addresses and reset passwords.
// Set the mount path as it is in serverURL
publicServerURL: 'http://localhost:1337/parse',
});
// 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();
// Serve static assets from the /public folder
app.use('/public', express.static(path.join(__dirname, '/public')));
// 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('Make sure to star the parse-server repo on GitHub!');
});
// There will be a test page available on the /test path of your server url
// Remove this before launching your app
app.get('/test', function(req, res) {
res.sendFile(path.join(__dirname, '/public/test.html'));
});
var port = process.env.PORT || 1337;
var httpServer = require('http').createServer(app);
httpServer.listen(port, function() {
console.log('parse-server-example running on port ' + port + '.');
});
// Set up parse dashboard
var config = {
"allowInsecureHTTP": true,
"apps": [
{
"serverURL": "http://localhost:1337/parse",
"appId": "xxx",
"masterKey": "xxx",
"appName": "name",
"production": true
}
],
"users": [
{
"user":"username",
"pass":"pass"
}
]
};
var dashboard = new ParseDashboard(config, config.allowInsecureHTTP);
var dashApp = express();
// make the Parse Dashboard available at /dashboard
dashApp.use('/dashboard', dashboard);
// Parse Server plays nicely with the rest of your web routes
dashApp.get('/', function(req, res) {
res.status(200).send('Parse Dashboard App');
});
var httpServerDash = require('http').createServer(dashApp);
httpServerDash.listen(4040, function() {
console.log('dashboard-server running on port 4040.');
});
One thing I noticed at Parse's documentation, is this: When using files on Parse, you will need to use the publicServerURL option in your Parse Server config. This is the URL that files will be accessed from, so it should be a URL that resolves to your Parse Server. Make sure to include your mount point in this URL.
The thing is that this documentation was written having in mind MongoDB, is on the same server with Parse, which in my case isn't.
Any ideas on what to do?
I had to replace the publicServerURL of parse server's config, from http://localhost:1337/parse to http://publicIP:1337/parse and everything worked out great!
If you want to work with files(images) download them, just use publicServerURL as mentioned #Sotiris Kaniras
I would add that the config.json is in ~/stack/parse/config.json. Also here is the difference between serverURL and publicServerURL
Difference between serverURL and publicServerURL on ParseServer
In my case, I needed to add publicServerURL parameter alongside with serverURL because it hasn't existed yet.
So both parameters(publicServerURL & serverURL) are complement, not mutually exclusive, use them both.

Getting "TypeError: db.createList is not a function"

I am currently doing a React, Express, Massivejs, postgreSql app. I am getting the error "TypeError: db.createList is not a function" anytime I'm trying to hit my post endpoint. I'm not sure how to remedy it since it looks correct.
My file structure:
My server file looks like this:
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var massive = require("massive");
var connectionString = 'postgress://LonnieMcGill#localhost/todo';
var massiveInstance = massive.connectSync({connectionString : connectionString})
var config = require('./config.js');
var app = module.exports = express();
app.set('db', massiveInstance);
var listCtrl = require('./controller/listCtrl.js');
// **************** Middleware ****************
app.use(express.static(__dirname + './../public'));
app.use(bodyParser.json());
// ****************** Endpoints ***************
app.post('/api/add/list', listCtrl.createList);
app.get('/api/get/list', listCtrl.createList);
app.get('*', function(req, res) {
res.sendFile('index.html', { root: './public'});
})
app.listen(config.port, function() { console.log('Server initiated on port', config.port); });
My controller looks like this:
var app = require('../server.js');
var db = app.get('db');
module.exports = {
createList: function(req, res, next) {
console.log('db'my);
db.createList([req.body.name], function(err, res) {
res.status(200).send('List created');
})
},
readList: function(req, res) {
db.readList(function(err, res) {
if (err) {
console.log("readList failed");
} else {
console.log("readList working " + req.body, req.params);
}
})
}
}
My createList.sql file looks like this:
INSERT INTO list (
name
)
VALUES (
$1
);
The documentation clarifies this issue. By default, the "db" folder should stay in the root directory of your project, and not where the scripts consuming the database are (in this case, "server/").
You must either move "db" to the root directory of your project (so as to be alongside "server", "public", etc.), or configure the scripts property to point to that location:
var massiveInstance = massive.connectSync({
scripts: "server/db",
connectionString
})

React Native Parse LiveQuery error on socket

I am having trouble connecting to the LiveQuery server that I setup on the server side of my React Native project. I followed the instructions on the site verbatim, but can only manage to get 'error on socket' when I connect with numerous attempts by the server to reconnect.
Here is my server setup:
liveQuery: {
classNames: ['BekonRequest'],
}
var port = 1337;
server.listen(port, function() {
console.log('parse-server running on port ' + port); });
var parseLiveQueryServer = ParseServer.createLiveQueryServer(server);
server.listen(port, function() {
console.log('parse-server running on port ' + port);
});
var parseLiveQueryServer = ParseServer.createLiveQueryServer(server);
And my client side code:
let requestQuery = new Parse.Query('BekonRequest');
requestQuery.equalTo("username", "broncos#nfl.com");
let subscription = requestQuery.subscribe();
subscription.on('create', (requests) => {
console.log(requests);
});
Can anyone see why I am not able to connect successfully?

Getting and "Error, wrong validation token" when trying to create a Facebook Chatbot

I'm trying to create a Facebook chatbot with NodeJS, Express, and a Heroku server.
I created my webhook on heroku and had it verified and saved by facebook. I then started adding code that would reply to the incoming messages and I can't seem to get it connected. It keeps saying "Error, wrong validation token" when I try to load my webhook in my browser. And when I try to send my bot a message I get no response. Even though I already had it verified and didn't change the code.
Here is my code:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var port = process.env.PORT || 3000;
// body parser middleware
app.use(bodyParser.urlencoded({ extended: true }));
// test route
//app.get('/', function (req, res) { res.status(200).send('Hello world!') });
app.get('/', function (req, res) {
if (req.query['hub.verify_token'] === '8FKU9XWeSjnZN4ae') {
res.send(req.query['hub.challenge']);
}
res.send('Error, wrong validation token');
})
app.post('/', function (req, res) {
messaging_events = req.body.entry[0].messaging;
for (i = 0; i < messaging_events.length; i++) {
event = req.body.entry[0].messaging[i];
sender = event.sender.id;
if (event.message && event.message.text) {
text = event.message.text;
sendTextMessage(sender, "Text received, echo: "+ text.substring(0, 200));
}
}
res.sendStatus(200);
});
// error handler
app.use(function (err, req, res, next) {
console.error(err.stack);
res.status(400).send(err.message);
});
app.listen(port, function () {
console.log('Listening on port ' + port);
});
var token = <myToken>;
function sendTextMessage(sender, text) {
messageData = {
text:text
}
request({
url: 'https://graph.facebook.com/v2.6/me/messages',
qs: {access_token:token},
method: 'POST',
json: {
recipient: {id:sender},
message: messageData,
}
}, function(error, response, body) {
if (error) {
console.log('Error sending message: ', error);
} else if (response.body.error) {
console.log('Error: ', response.body.error);
}
});
}
So I'm confused as to why nothing is happening and why I'm getting that error. I feel like I'm missing a whole step. I am following this tutorial by the way: https://developers.facebook.com/docs/messenger-platform/quickstart
Any help is appreciated. Thanks!
Edit: Here are my heroku logs
Do not post your full access tokens here!
Have you tested the output of the challenge? Since it's just a GET and you know all values you can try it yourself: your-app-domain.com/your-callback-url?hub_mode=subscribe&hub_verify_token=the_token_you_set_in_your_app_config&hub_challenge=ping which sould print 'ping' if everything work fine.
Make sure you add sendStatus(200) to the hub challenge response, too.
You need to subscribe your page to the app first. To do so make a POST request to /your-page-id/subscribed_apps which should return "success". You can make a GET request to the same endpoint afterwards to double check your app is subscribed to your page
You did not mention which events you subscribed to (needs to be message_deliveries, messages, messaging_optins, messaging_postbacks)
Make sure the webhooks tab in your app dashboard now says "complete"
Test again
You are actually using "request" but you are never importing it anywhere. Here's how to fix it:
var request = require("request")
Once you have added that to your index.js or app.js file (basically whatever this file is), make sure you do:
npm install request --save
This should fix it. Unfortunately, Heroku doesn't error out and say that it does not know what "request" is and that's why it was so hard to figure this out in the first place!