Migration from Parse to Heroku and Parse Server

Introduction

Currency application

I have a small Android application Currency. Both client and server are open-sourced. In this guide we will talk about server side. Its functions are simple: once per hour Parse grabbs currency exchange adverts from 3rd party service, clears old adverts and saves new. Client is able to fetch data from server, show it and put created by user new data. In this post I’ll show you in practise how you can migrate from Parse to Heroku.

Step 0

Preparation

First of all official guide is your best friend. Do all steps carefully and success will attend you. This post will be your additional guide and example.

So let’s do it. Create your heroku project and add mlab add-on. Follow by mlab instruction. Further, you can use add-on pre-created user or create your own.

Note: for installing add-ons you need to verify your Heroku account by providing information about valid credit card.

After installation and registration you will have empty mongo database:

Tip: you can find username and password of created by mlab user under Heroku project settings. Click ‘Reveal Config Vars’ button. MONGODB_URI is what you are looking for. It should be similar to this:
mongodb://username:password@ds011311.mlab.com:11311/heroku_6ng6d03h
If you created your own user don’t forget to change MONGODB_URI variable.

Step 1

Database migration

Go to new Parse dashboard and select your application. Follow instructions of the first step of official guide. Start your migration. Below you can see screenshots of some final migration steps.

Click ‘Finalize’ when it becomes available:

Don’t afraid, click ‘Okay’:

Read some congrats. Parse have got rid of you, yeah:

Process of database migration is complete:

Step 2

Set up Parse Server

Great! Now we need to set up Parse Server which is a kind of middleware between your client application and data in database.

Firstly, get copy of Parse Server Example. I forked it and renamed. Then I cloned repository to my computer.

Tip: you may use ‘Deploy to Heroku’ button but I strongly recommend you not to do this. The reason is this bug.

Now change APP_ID, MASTER_KEY, SERVER_URL environment variables in app.json file.

Now you can upload it to heroku and test your database. To make upload simple I advice you to bind github repository to your heroku project and enable automatic deploys. Really cool feature.

Tip: You also can add heroku remote to git with simple command. Discover more here.
$ heroku git:remote -a your-heroku-project-name
Note: this and some other console commands require Heroku Toolbelt.

After successfull deployment go to your-heroku-project-name.herokuapp.com/test and follow by check steps.

Note: If you notice we didn’t set up credentials for your database in code. It is fetched from MONGODB_URI environment variable.

Okay! It works but for now this is only connection with your database without your cloud code or something additional.

Step 3

Cloud code

Now you have copy of parse server and can adapt it to your needs.

I removed unnecessary files, moved environment variables from app.json to heroku project settings, removed test endpoint from index.js, removed public/test.html and created index endpoint instead of test.

You can see index page here: https://currencyua.herokuapp.com

All these thing are personal, you may or may not do this.

Let’s deal with Parse Cloud Code. I had background job in Parse. Once per hour it grabbed currency exchange adverts from 3rd party service, cleared old adverts and saved new. My legacy Cloud Code can be found at this gist.

If your cloud code contains only functions without jobs — you are a lucky person and can skip to step 4. But if you have jobs — you’ll need to change code because Parse Server doesn’t have it. Likely, there is Heroku Scheduler add-on which can be used as alternative solution to Parse jobs.

Copy your code to /cloud folder. Turn parse jobs into functions.

Example:
Parse.Cloud.job(“currencyJob”, function(request, status) // old
Parse.Cloud.define(“currencyServerJob”, function(request, response) //new

Don’t forget to make all accompanying stuff, e.g. rename status to response.

My new Cloud Code can be found here.

Now install Heroku Scheduler. You can do it within Heroku Toolbelt:

heroku addons:create scheduler:standard

Create folder bin and file named after your job. In my example this is currencyjob file:

#!/usr/bin/env node
var Parse = require(‘parse/node’);
Parse.initialize(process.env.APP_ID, process.env.JS_KEY, process.env.MASTER_KEY);
Parse.serverURL = process.env.SERVER_URL;
Parse.Cloud.run(“currencyServerJob”);

The only purpose of this code is to run currencyServerJob function. You can test if it works using next command:

heroku run node bin/currencyjob

If you get Operation timed out message try another command:

heroku run:detached node bin/currencyjob

You should get similar output:

Running node bin/currencyjob on currencyua… up, run.1269
Run heroku logs — app currencyua — dyno run.1269 to view the output.

Run suggested command to view output:

2016–04–20T19:57:52.305429+00:00 heroku[run.1269]: Starting process with command `node bin/currencyjob`
2016–04–20T19:57:52.993938+00:00 heroku[run.1269]: State changed from starting to up
2016–04–20T19:58:18.456086+00:00 heroku[run.1269]: Process exited with status 0
2016–04–20T19:58:18.474880+00:00 heroku[run.1269]: State changed from up to complete

No errors, everything works. Now let’s set up Scheduler task. Go to add-on settings and create new job:

Link: good article about Heroku Scheduler.

Push your code, wait until heroku application is built and breathe freely — the hardest part of the work is done.

If you have another things to migrate — follow official guide.

Step 4

Finalize

Now I recommend you to stop your parse jobs if you haven’t done it yet.

Also you can migrate to 3rd party admin panel (analogue of Parse) adminca.com

Now all you need is to change enpoints in your client application. Here is guide. In my Android application I changed parse initialization part:

Parse.initialize(new Parse.Configuration.Builder(context)
.applicationId(context.getString(R.string.parse_app_id))
.clientKey(context.getString(R.string.parse_client_key))
.server("http://currencyua.herokuapp.com/parse/") // The trailing slash is important.
.build());

Epilogue

As you see the process can be painful in some moments. But not very hard and can be done in a couple of hours. Don’t be afraid and migrate your projects!

Tip: If you are not familiar with Heroku dynos, read it in help to avoid unpredictable cost spend.

You may follow me on Github if you like this article.