Hacking Parse open source with some workarounds

Hacking Parse open source with some workarounds

 

Parse server is one of the best alternatives for Parse. But as we have seen in our last article “Parse open-source is moving fast but still has some features to be opened up. See which” there are a few features that are not available in the open-source version of Parse. But there are alternatives for each of those features. Let’s take a quick look at some of the ways to close the gaps between Parse Server and make it work closer to Parse.

Analytics

Google Analytics is one of the best alternatives for Mobile Apps as it lets you measure the full value of your app across all key stages right from first discovery and download to in-app conversions. One could implement the routes in analytics.js and then send the event to another analytics provider like Google Analytics. AnalyticsRouter.js is the entity responsible for exposing the route on Parse Server. We need an adapter to integrate this entity with the external service such as Google Analytics.
The Parse team has released the router, but the Parse community has not implemented the adapters to any of the external analytics service such as Google Analytics, Flurry, Amazon Mobile Analytics, or Mixpanel. Maybe, currently, Analytics is not their priority.

 

AnalyticsRouter

 

As you can see on the picture bellow the adapters to Analytics external integration are not implemented on Parse-server.

 

ParseServerAdapters

Authentication

As discussed in the previous blog, Parse server has emerged blessing in disguise. So there is no need to either worry about the open issues reported on OAuth anymore or to find an alternative solution to the authentication feature of Parse. Parse.com team released the adapters and the community has implemented the components to integrate your app with facebook, twitter, google, meetup, GitHub, LinkedIn and Instagram. If you wish to do this integration, you need to change some parameters in your Parse server source code. Here’s how you can do it.

Using the file index.js insert the following code:

{
  oauth: {
   twitter: {
     consumer_key: "", // REQUIRED
     consumer_secret: "" // REQUIRED
   },
   facebook: {
     appIds: "FACEBOOK APP ID"
   }
  }

}

into the section where Parse server is instantiated as below:

var api = new ParseServer({
  oauth:{}
  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 || 'http://localhost:1337/parse',  // Don't forget to change to https if needed
  liveQuery: {
    classNames: ["Posts", "Comments"] // List of classes to support for query subscriptions
  }
});

At back4app, we have already made available Facebook via management panel.

oAuth-fb

Global config

Right after we published our last blog we had an update from Parse.com about the availability of Global Config on Parse Server.
If you have Open Source Parse Server and Parse Dashboard, running on your infrastructure, you need to update your version of the Parse Server and Parse Dashboard to configure Parse config.
parse_config
On back4app, we will release this feature on our backboard in the next few days.

 

Push notifications

Push send feature was available since 11th Feb 2016, but it was not configurable on the Dashboard. Now they have enabled Push on the dashboard, and you can use in the same way that you did on parse.com. As Parse.com announced on its blog:

Powerful targeting, content building and rich options for sending pushes to your users is one of the pillars of Parse, and the ease of use of Parse Push is one of the things that makes Parse great. Now, we are bringing that ease of use to the Open Source Parse Server and Parse Dashboard, running on your own infrastructure. If you’ve configured push already, all you need to do is update your version of the Parse Server and Parse Dashboard and you can start sending pushes.

push_dash

On back4app, we will release this feature on our backboard in the next few days.

Background jobs

For running background jobs, one could choose Kue. Kue is a priority job queue backed by Redis, built for node.js.

Kue

You will need to install the Kue project into the Parse Server as an npm install. After installing Kue, you can use jobs on your cloud codes directly.

$ npm install kue
//Create a job with kue.createQueue()
var kue = require('kue')
  , queue = kue.createQueue();

Calling queue.create() with the type of job (“email”), and arbitrary job data will return a Job, which can then be save()ed, adding it to redis, with a default priority level of “normal.” The save() method optionally accepts a callback, responding with an error if something goes wrong. The title key is special-cased, and will display in the job listings within the UI, making it easier to find a specific job.

var job = queue.create('email', {
    title: 'welcome email for tj'
  , to: 'tj@learnboost.com'
  , template: 'welcome-email'
}).save( function(err){
   if( !err ) console.log( job.id );
});

Jobs may be queued for an arbitrary time by invoking the .delay(ms) method, where you need pass the number of milliseconds relative to now or you can pass a JavaScript Date object with a particular time in the future. This automatically flags the Job as “delayed”.

var email = queue.create('email', {
    title: 'Account renewal required'
  , to: 'tj@learnboost.com'
  , template: 'renewal-email'
}).delay(milliseconds)
  .priority('high')
  .save();

Kue will check the delayed jobs with a timer, promoting them if the scheduled delay has been exceeded, defaulting to a check of top 1000 jobs every second.

There are other features such as job event and progress pubsub, job TTL, optional retries with backoff, graceful workers shutdown, job specific logging additionally available with Kue.

 

System emails

Parse Open source community already provides a workaround solution for sending reset password and confirmation emails.To configure system emails, you have to modify the index.js.

Verifying user email addresses and enabling password reset via email requries an email adapter. As part of the parse-server package we provide an adapter for sending email through Mailgun. To use it, sign up for Mailgun, and add this to your initialization code:

var server = ParseServer({
  ...otherOptions,
  // Enable email verification
  verifyUserEmails: true,
  // The public URL of your app.
  // This will appear in the link that is used to verify email addresses and reset passwords.
  publicServerURL: 'https://example.com',
  // Your apps name. This will appear in the subject and body of the emails that are sent.
  appName: 'Parse App',
  // The email adapter
  emailAdapter: {
    module: 'parse-server-simple-mailgun-adapter',
    options: {
      // The address that your emails come from
      fromAddress: 'parse@example.com',
      // Your domain from mailgun.com
      domain: 'example.com',
      // Your API key from mailgun.com
      apiKey: 'key-mykey',
    }
  }
});

You can also use sendgrid email adapters. Using the same code above change the parameter module to the value:’parse-server-sendgrid-adapter’.

 

Auto-indexing

The hosted Parse automatically adds indexes based on the incoming query stream. But to improve performance, you need some support to manage the indexes on the Mongo-DB instances. The Parse community is more focused on developing the functional features and has given a lesser priority to such performance issues. For now, there is no workaround available for auto-indexing and the Parse community is yet to come up with a discussion on when they are planning to provide this performance add-on.

 

Logs

 

You need to depend on prompt logs for now until the open-source Dashboard provides the console.log and errors outputs. You can add “VERBOSE”: “1” argument as an environment variable that allows seeing all the queries executed by Parse server. Using Linux on your server the parse-server should write the logs to the stdout/stderr as well as in the log folder(/logs).

 

Cloud code

 

The Parse JavaScript SDK in npm is a library that gives you access to the powerful Parse cloud platform from your JavaScript app. Cloud Code environments are loaded and unloaded individually for each request, while node.js services typically serve multiple requests at a time. So using Parse JavaScript SDK, you can switch from Cloud code to node.js.

You can insert any cloud function into a main.js (or call it by any other file name) and reference it into index.JS on New ParseServer(); command.

For instance, let’s say you have a cloud function in helper.js. Here’s how you write the main.js

main.js
var Helper = require("./helper.js");
Parse.Cloud.define("hello", function(request, response) {
response.success("Hello world!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
});
helper.js
// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
Parse.Cloud.define("test", function(request, response) {
response.success("Hello world!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
});

CLP

 

With the introduction of new dashboard, the Parse Server has the necessary endpoints to set CLPs. The newest version of the Parse Dashboard lets you set CLPs, as long as you are on the latest version of Parse Server. The Parse Dashboard is updated to understand this new format in the permissions dialog.

 

Webhooks

 

There are two main types of webhooks. Mapping a function to an external APIs is the first. To execute javascript code when some events happen in saving and deleting records on Parse.com classes is the second.
The webhooks are javascript code running on the server as well as the Parse cloud codes. You may even notice that Parse.com has released on its documentation a guide of how to program advanced cloud codes(before saveafter savebefore deleteafter delete). These docs are guidelines of how to implement webhooks with cloud codes.
Thus, the solution for webhooks is to implement Cloud Codes on Parse Open Source.
To implement the webhook (function or triggers type) on your app you can use the following code into your main.js cloud code file.

 

var http = require('http');
var url = require('url');

function webhook(urlStr, data, cb) {
  var postData = JSON.stringify(data);

  var options = url.parse(urlStr);
  options.method = 'POST';
  options.headers = {'Content-Type': 'application/json', 'Content-Length': postData.length};

  var req = http.request(options, function(res) {
    var body = '';
    res.setEncoding('utf8');
    res.on('data', function(chunk) {
      body += chunk;
    });
    res.on('end', function() {
      cb(null, body);
    })
  });

  req.on('error', function(err) {
    cb(err);
  });

  req.write(postData);
  req.end();
}

// Function Webhook
Parse.Cloud.define('hello', function(request, response) {
  var urlStr = ''; // TODO: replace with webhook URL
  var data = {functionName: 'hello', params: request.params};
  webhook(urlStr, data, function(err, data) {
    if (err) {
      response.error(err);
    } else {
      response.success(data);
    }
  });
});

// Trigger Webhook
Parse.Cloud.afterSave('Person', function(request) {
  var urlStr = ''; // TODO: replace with webhook URL
  var data = {triggerName: 'afterSave'};
  webhook(urlStr, data, function(err, data) {
    if (err) {
      console.error(err);
    } else {
      console.log(data);
    }
  });
});

 

Uptime monitoring

 

When you host the Parse Server instance on a third-party service provider, you need to depend on the uptime they provide. You can use Pingdom to monitor URL. You need to log in to my Pingdom. Add the URL that you would like to monitor and configure other settings on their dashboard.

 

 

You must be relieved to see these alternatives for the missing features in Parse Server. There’s something more to be happy about. Look out for our next post where we detail how back4app is bringing out Push, global config and CLPs in their application.

 

Did you liked this article? Share with your friends:

 


Comments ( 3 )

  1. ReplyemDrake.
    I tried to follow your examples here, but the background jobs just break my app. After I add the kue to my index.js my app no longer works. I have an ios app that when I try to query after adding kue returns this error: Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.} I was wondering if you know of any work around for this, or if you have encountered anything like this.
    • ReplyemDrake.
      Do you know of any tutorial for using Kue with parse server on heroku. I only found this, and it doesn't really help me with my jobs.
      • ReplyDavi Macedo
        Hi, Emdrake. I don't have a specific tutorial for Heroku. But you can follow two tips: 1) If you use Parse.Cloud.job it won't work. You have to use change all your jobs to cloud functions. 2) Make sure you have installed kue before using it: npm install kue --save

Leave a reply

Your email address will not be published.