Guide: How To Migrate Your Parse App To Parse Server With Heroku And mLab

Written by: Reinder de Vries, January 31 2016, in Guide, Programming

On January 28th Parse announced it will be shutting down its service. They’re winding down the done-for-you Platform-as-a-service, fully retiring it on January 28, 2017.

That’s bad news for over 500.000 developers who relied on the service since 2011. Parse was acquired in 2013 by Facebook for $ 85 million. Back then it was a risky acquisition, which Facebook needed to get a foothold in the mobile market.

Facebook’s recent earnings report shows a growth in mobile advertising revenue of 52%, comparing Q4 of 2014 and 2015, which clearly shows they’ve landed in mobile. With the rise in competition of cloud services by the likes of Amazon, Microsoft and Google, you could argue Facebook doesn’t need Parse anymore.

App developers that use Parse have several options to migrate. Alternatives include Firebase, and the new Parse Server stack.

This guide will show you how you can migrate your app from Parse to Parse Server by making use of the free Heroku and mLab services. The guide starts with the setup of the Paws app, a minimal Instagram-like iOS app (cat pictures!).

You’ll set up the app, migrate it to mLab, then start a Heroku instance and connect it to the app. Prior I’ll explain a bit about the Parse and Parse Server architecture.

This code guide can be used for app makers who want to migrate their app from Parse to Parse Server. It’s also suitable for app makers who have never used Parse (and don’t have a Parse account) and wish to set up a fresh Parse Server app.

Let’s get started!

0. Overview: What Ingredients Do You Need?

Parse is technically a Backend-as-a-Service provider. It hosts a service you can use to store structured information and provides you with an API endpoint you can use to create and edit your app’s data. Parse has many SDKs for platforms such as iOS, Android and NodeJS (JavaScript).

In a diagram, this is what the Parse stack looks like (Figure 1):

Figure 1, 2 and 3

Figure 1, 2 and 3

As an app maker, you only had to code your app’s client-side code and manage the data in a easy-to-use administration tool. No need to worry about scaling the back-end, building indices or managing your data at a microlevel. You could essentially tap your app into a spreadsheet, and never worry about it. Your app connected through the high-level SDK to Parse, and Parse managed its own databases.

When migrating to Parse Server, the architecture is different (Figure 2). Instead of only working with the Parse SDK, you manage your own Heroku instance that runs Parse Server, and manage your own MongoDB database that connects to Parse Server. You’re responsible for scaling and maintaining your own back-end.

If you map out different back-end architectures on a scale from “hard” to “easy”, and “unmanaged” to “done-for-you”, you end up with Figure 3. As you can see, it requires dedicated sysops time to run a bare-metal server or Virtual Private Server (VPS, or cloud server), while it takes zero effort for the app maker to run the Parse BaaS. Somewhere in the middle between VPS and Parse you’ll find Heroku and mLab (and equivalents), not as hard as maintaining a VPS, but not as easy as the original Parse.

Parse strongly recommends you to migrate to Parse Server as soon as possible. In the diagram you see a dotted line, which indicates an intermediary state in which you still communicate with the Parse back-end, but in which Parse communicates with your self-hosted MongoDB database.

This allows for a two-step migration:

  1. First, you set up a MongoDB database (on mLab, or equivalent) and let Parse send your data to it. Your current app clients don’t require a code change, because the Parse API endpoint doesn’t change.
  2. Second, you set up Parse Server (on Heroku, or equivalent) and connect it to your MongoDB database. You publish an update for your app that points to the new Parse Server API endpoint. App users that didn’t update will use the MongoDB database through the original Parse, and updated users will use the new Parse Server. In either case, your app will point to a single database. While the migration is taking place, Parse will keep track of additions and will sync them after the initial migration completes.

Both steps are documented in this code guide. Even if you didn’t use Parse before today, you can use this code guide to learn how to set up a fresh Parse Server for your app.

While it may seem like an obvious migration schedule, it’s important to take note of the changes in architecture. You can read more on this in the conclusion of this code guide.

Are you going to use Parse Server for your next app?

Get curated iOS app articles and resources right in your inbox. Smart app makers stay up-to-date on Swift development, growth hacking and App Store Optimization. Trusted by 11.000+ app developers and marketers. Sent out weekly.
Yes, Sign Me Up!

1. Getting Started: Set Up The “Paws” App

Alright, first lets get started with the original Paws app. The app is part of a code guide originally published on

The Paws app is a minimal Instagram-clone that shows pictures of cats in a vertical timeline. Users can upvote a cat picture by double-tapping on its image. The project uses the Parse and ParseUI pods (with CocoaPods), and relies on the now shut down Parse.

In this code guide, you’ll first set up the Paws project as if it were fully reliant on Parse (an “existing project migration”) and then two-step migrate it to Parse Server.

Getting The Paws Code From GitHub

First, download the Paws Xcode project from GitHub at Download the ZIP and unzip it in a convenient location. If you have Git installed, you can of course also clone the project.

Use Terminal to cd into the project’s root directory, like this:

Terminal: cd into Paws directory

Terminal: cd into Paws directory

Next up, make sure you’ve got the latest versions of the pods used in the project. In the same root directory, type this on the command-line:

$ pod update

(Note: you can omit the $, it just indicates the code block above should be input on the command-line. Make sure you press the Enter key after you type in a Terminal command.)

If you don’t have CocoaPods installed on your Mac, follow the steps documented here to install it.

CocoaPods will now read the Podfile, which contains a reference to pods Parse and ParseUI, and attempts to download their latest versions. It also builds the pods and adds them to our Paws.xcworkspace workspace file.

You’re likely to see something similar to the following output in Terminal:

Terminal: pod update

Terminal: pod update

Next up, open the Paws.xcworkspace file. You can use Finder to locate the file, or open Xcode and then open the right workspace. It’s important you don’t open the Paws.xcodeproj file, but instead use the workspace file.

Press the Command-B keys to build the project, and verify that the project doesn’t generate any errors. If you were to run the project in its current state on your iPhone or the iOS Simulator, it wouldn’t run, because the configuration parameters haven’t been set. We’ll do that in a minute!

Uploading The App Data To Parse

Because we’re recreating an existing Parse project, we need to update the app’s data to Parse. We could of course import it right into the MongoDB database we are creating in the next step, but that would defeat the purpose of experiencing what it’s like to migrate an existing app.

  • First, download the following file: It contains the data for the app, including the URLs of the cat photos, photo credit information, and the names of the cats.
  • Second, unzip the file in a convenient location.

Next up, go to and log in with your account credentials.

Note: Unfortunately, if you don’t have an account already you can’t create a new one due to the shutdown of the Parse service. Don’t worry, you can still use Parse Server! Skip ahead of part 2, creating a MongoDB database with mLab, and follow the special instructions on importing the app data in mLab.

On your Parse dashboard, click the Create a new app button. Name the app “Paws” and set its database type to Parse Data. Once the app is created, you’ll be taken to the Browser.

Parse Dashboard

Parse Dashboard

Click on the ... three-dotted button in the bottom-left of the interface (see image above), then choose Leave Beta. This will take you to the previous version of the Parse Dashboard UI. Why the change? Well, for some reason the new UI doesn’t have a button to import data into Parse…

Next, locate your Paws app in the old UI and make sure to navigate to Parse Core. Your screen should now look like this:

Old Parse Core

Old Parse Core

Next, do this:

  • First, click the Import button. A dialog box appears.
  • Then, click Browse. Locate the data file you previously unzipped. Make sure to upload the .json file, not the .zip file.
  • Then, once the file is uploaded, choose Custom for Collection Type and name the collection Cat.
  • Finally, click Finish Import.

Connecting Parse To The Paws App

Now, click Switch to new Dashboard in the bottom-left corner of the screen. In the new UI, open the Paws app once more, then go to App Settings -> Security and Keys.

Locate the following two text strings. You’ll need them later to connect the Paws app to Parse.

  • Application ID
  • Client Key
Parse: App Keys

Parse: App Keys

Next, open the Paws workspace in Xcode and open the AppDelegate.swift file. At the top there’s a couple of configuration code lines. Do this:

  • First, uncomment (remove the //) the first Parse.setApplicationId(... line.
  • Then, replace the first ... with the Application ID you located earlier.
  • Then, replace the second .... with the Client Key you located earlier.
  • Finally, comment the entire let config = ... to ... Parse.initializeWithConfiguration(config); code block. You’ll use it later.

The first part of the code block now looks like this:

Parse.setApplicationId("<your application id>", clientKey: "<your client key>");


/*let config = ParseClientConfiguration(block: {  
    (ParseMutableClientConfiguration) -> Void in

    ParseMutableClientConfiguration.applicationId = "...";  
    ParseMutableClientConfiguration.clientKey = "...";  
    ParseMutableClientConfiguration.server = "...";  


let tableVC:CatsTableViewController = CatsTableViewController(className: "Cat");  
tableVC.title = "Paws";


Finally, run the app by pressing Command-R or by clicking on the Run button at the top-left of Xcode. Make sure you’ve selected an iPhone Simulator device, or connected your own iPhone or iPod Touch. The app should compile and run, resulting in a screen similar to this:

Xcode: Running The Paws App

Xcode: Running The Paws App

OK, now imagine the following happens:

  1. You publish the beautiful Paws app on the App Store and amass a large number of monthly active users. You sit back and enjoy your app with its convenient Parse back-end.
  2. Parse announces it’s shutting down its service…
  3. You FREAK OUT! What now? I mean, you had two certainties in your life: Parse and taxes!

Fortunately, the fine folks at Parse transmuted their Platform-as-a-Service in a well-coded Parse Server NodeJS/Express package. You can essentially run the (almost) full Parse service on any webserver that supports MongoDB and NodeJS. Awesome!

2. Creating A MongoDB Database With mLab

OK. We saw in the overview at the top of this article that Parse will now run on two new services: Heroku and mLab. Essentially, Heroku hosts and runs the Parse Server code and mLab hosts the app’s data in a MongoDB database.

Let’s first set up the mLab service. At this point you’ve either recreated the Paws app with the original Parse, or you didn’t have a Parse account but still want to use Parse Server.

Deploying The MongoDB Database

First, make sure you have a mLab account by signing up at Then, log into your new account.

Note: you need to verify your email address before you can create any new deployments. Sign up, wait for the verification email to arrive in your inbox, click the link, then get back to the mLab dashboard.

On the dashboard, click the Create New button. On the page Create new subscription page that appears, do the following:

  • First, choose Amazon Web Services as cloud provider.
  • Then, choose Amazon’s US East (Virginia) Region (us-east–1) as location.
  • Then, select the Single Node tab and choose the Sandbox option. This is mLab’s free tier, which has more than enough capacity for our app.
  • Then, name the database paws.
  • Finally, click Create new MongoDB deployment.

The new database is created. You can of course choose different MongoDB options depending on the requirements of your app. Keep in mind that the original Parse service compressed your app’s data. Parse recommends to 10x the size of your Parse data when creating a new MongoDB database.

If all went OK, you’ll be redirected to your mLab dashboard which shows the newly created database. Click on the database to open its detail screen. Note the mongodb:// URL at the top, we’ll need it later.

mLab: Database details

mLab: Database details

Next, do this:

  • First, click the Users tab.
  • Then, click Add database user.
  • Then, in the dialog that appears, input paws as username and input a strong password, then click Create. Make sure to leave the Make read-only checkbox unticked.

Make sure you note the paws username and its password somewhere safe. You will need it later.

Synchronizing Parse With mLab

You can skip this step if you don’t have a Parse account. Continue with “Importing Data In mLab”.

Copy the mongodb:// URL you located earlier to a text file and replace the <dbuser> and <dbpassword> with the username and password you just created. The result should look something like this:

mongodb://paws:[email protected]:33297/paws

Then, switch back to the Parse Dashboard at and open your Paws app. Next, go to App Settings -> General and click on the Migrate button (in red).

Then, paste the mongodb:// URL in the input field and click Begin the migration. You’ll be taken to a screen that shows the process of the migration. Parse will now send all your data to mLab, which shouldn’t take long.

Parse Migration

Parse Migration

Note: the migration is essentially complete when the first bar turns green. Parse is still looking for new data that was entered since the migration, but because our Paws app isn’t used in a production environment,no new data is added.

Once all the bars are green, and you’ve had the chance to manually verify the data, Parse will switch to using your self-hosted MongoDB database instead of the Parse hosted database. That’s pretty cool! Parse still takes in requests from your connected app clients (the one’s your users use), but instead of reading and writing to the Parse hosted database, it reads and writes from and to your own self-hosted database on mLab.

OK, that’s it! This concludes the first part of the migration. You can skip ahead to Deploying Parse Server On Heroku.

Importing Data In mLab

Only complete these steps if you don’t have a Parse account.

OK, you don’t have a Parse account but still wanted to follow this code guide to learn how to deploy Parse Server. You’re essentially creating a fresh new Paws app, but directly deploying it on Heroku and mLab without using the original Parse.

Note: At this point, you need to have the Paws source code set up, have created a mLab account, created the paws MongoDB database, and created the paws database user. Make sure you’re logged into your mLab account and open your dashboard at

In order to get the app data into your MongoDB database, you’ll need to import it with a JSON file. To do that, you need to have the MongoDB tools installed on your Mac’s OS X.

Before you can install the tools, you need to install Homebrew. Homebrew is a package manager for OS X and you can use it to install several command-line tools Apple didn’t install by default on OS X. One of those tools is MongoDB.

Note: Read on how to install Homebrew.

Once you’ve installed Homebrew, run the following Terminal command to ensure you’ve got the latest version of Homebrew.

$ brew update

Next, install MongoDB with this command:

$ brew install mongodb

Next, run the following command to verify the toolset was installed correctly:

$ mongoimport --help

Next, download the following file: and unzip it in a convenient location. Make sure the resulting unzipped directory is called paws.

Next, go to your mLab dashboard, open the paws database and click the Tools tab. You’re now on a page that lists a number of CLI commands to work with MongoDB.

Find the first one, right below Import database. It’s similar to:

$ mongorestore -h -d paws -u <user> -p <password> <input db directory>

You have just installed this mongorestore command with Homebrew. The tool restores a MongoDB database, based on parameters, essentially entering data into the empty database you created previously.

Before you can use the command, you need to configure the parameters. It’s easiest if you first copy the entire command from your mLab Tools page to a text file.

Then, edit the parameters one by one:

  • First, replace <user> with paws
  • Second, replace <password> with the password you entered earlier.
  • Third, replace <input db directory> with paws.

The entire command now looks similar to this:

$ mongorestore -h -d paws -u paws -p password1234 paws

Don’t input the command in Terminal just yet. First, use Terminal and cd to navigate to the directory you unzipped the in. For instance, if you downloaded the ZIP file to your downloads directory at ~/Downloads, do the following:

$ cd ~/Downloads

Once you’ve navigated to the right directory, copy and paste the mongorestore command from the text file into Terminal and press enter. The result in Terminal looks something like this:

Terminal: Restore MongoDB Database

Terminal: Restore MongoDB Database

As you can see, I’ve unzipped the ZIP in ~/Downloads as subdirectory paws and restore that database to a MongoDB called paws-test with username paws and password abcd1234.

Verify that the data import went OK by checking your MongoDB’s collections with the Collections tab in the dashboard.

mLab: Collections OK!

mLab: Collections OK!

Alright! That’s it for migrating to MongoDB. Because the steps involved are quite complex, this is a high-level recap:

  1. Get a mLab account and log in.
  2. Create a paws MongoDB database (free tier on AWS, US East)
  3. Create a paws user, note the password somewhere.
  4. If you have a Parse account and want to migrate the app’s data:
    • Note the MongoDB URI
    • Replace the <dbuser> and <dbpassword> with the right values.
    • Go to Parse, choose Migrate, input the URI and start the migration.
    • When it completes, verify the data and complete the migration.
  5. If you don’t have a Parse account and want to start a fresh app with Parse Server:
    • Install Homebrew, the MongoDB command-line tools, and verify mongorestore works OK.
    • Go to the Tools tab of your database in mLab.
    • Note the Import database CLI command, copy it to a text file, and change its parameters to reflect your values (username, password and directory).
    • Use Terminal and cd to navigate to the right directory (~/Downloads if you unzipped the ZIP data file in that directory.)
    • Paste the mongorestore command from the text file in Terminal and execute the command.
  6. Finish!

Note: Remember that you can get your MongoDB URI from your mLab dashboard, you’ll need it later.

3. Deploying Parse Server On Heroku

OK. Now that the MongoDB database is set up to contain your app’s data, we need something that hosts and executes the Parse Server code.

Parse Server, the roll-your-own-Parse package, is a NodeJS Express application. That means you can run it on any server that’s capable of running NodeJS, such as an Amazon Web Services instance, a Digital Ocean or Linode VPS, and even Microsoft’s Azure. In this code we’ll be using Heroku.

Heroku is a Platform-as-a-Service, just like Parse, AWS, Digital Ocean, etc. You read in the overview that Parse is a done-for-you, managed and scalable Platform-as-a-Service.

If you would draw a line, put Parse on the right, and a bare-metal (or VPS) server on the left, you can place Heroku somewhere in the middle. You don’t have to manage your own virtual servers, but you still have to manage your own app instances. Parse did that all for you, which meant you essentially didn’t have to worry about scaling your back-end anymore.

With Heroku you create containerized instances of your app. One container for every Parse Server app. You’ll connect the app with your MongoDB database, through a configuration parameter which you’ll set to that MongoDB URI you noted earlier.

Let’s get started!

Installing The Heroku Toolbelt

Just like with MongoDB, much of the configuration of Heroku is done on the command-line. Before you have access to these CLI tools, you need to install them.

In order to install, do this:

  • First, go to
  • Then, download the Toolbelt for Mac OS X (or other operating systems, if applicable).
  • Then, once the download finishes, open the PKG file and follow the installation instructions.
  • Finally, to verify the installation is complete, type into Terminal the command $ heroku --help. If you’re seeing the CLI command options, all is OK.

Getting The Parse Server Example Sourcecode

In this code guide we’ll be working with the Parse Server example project. You can find it on GitHub:

You now need to download the source code on your local computer. Do this:

  • First, open Terminal and cd to your home directory: $ cd ~.
  • Then, create a new directory called heroku with $ mkdir heroku.
  • Then, cd into the new directory with $ cd heroku.
  • Then, clone the parse-server-example with Git in the current directory. You do that by typing: $ git clone Git will now download the source code and put it in a new directory called parse-server-example.
Terminal: Cloning Parse Server Example Sourcecode

Terminal: Cloning Parse Server Example Sourcecode

Setting The Parse Application ID And Client Key

Before the Paws iOS app can communicate with the Parse Server we’re setting up, it needs to authenticate itself with Parse Server. Authentication works sort of like a password and in our case, the password consists of an Application ID token and a Client Key token.

Previously, Parse generated and kept these two tokens (random strings of text), but with Parse Server you need to set them yourself.

In order to do that, open the file index.js in the ~/heroku/parse-server-example directory with your favorite text editor. Use Finder to navigate to your home directory, then open the directory called heroku, then open parse-server-example, then open the index.js file.

Locate the JavaScript code line that starts with var api = new ParseServer({ ....

Setting The Parse Application ID And Client Key

Setting The Parse Application ID And Client Key

With this code block, a new Parse Server is created with a number of configuration parameters. For instance, the databaseURI is set according to the environment variable we’ll set later in Heroku, DATABASE_URI. Also, the appId and masterKey are being set.

At this point you need to generate three text strings of random characters. You can do that in two ways:

  1. Copying the tokens from your Parse Dashboard:
    • First, open your Parse Dashboard and go to your app, then go to App Settings -> Security And Keys.
    • Then, Locate the three keys: Application ID, Client Key and Master Key (bottom, need to click Show Master Key first).
  2. If you don’t have Parse, generate three new tokens with
    • First, go to
    • Then, set the strings to be 20 characters long and tick all the boxes for Numeric, Uppercase and Lowercase characters. Set the strings to be unique, then click Get strings.
    • Then, pick three of the 10 random strings you just generated.

If all went OK, you now have three random text strings. With the strings, do the following:

  • First, get back to that index.js file in your text editor and locate the right code block again.
  • Then, replace myAppId with one of the random text strings. Make sure you type the string between single quotes.
  • Then, replace myMasterKey with one of the random text strings. Also between single quotes.
  • Then, type a comma , at the end of the line that says masterKey.
  • Then, put a newline after that comma, and type this: clientKey: '<random text string>'. Instead of <random text string>, type the third and last random text string you got earlier. (You’ve essentially appended one key-value item to the configuration dictionary.)
  • That’s it!

The entire code block now looks similar to this:

var api = new ParseServer({  
    databaseURI: process.env.DATABASE_URI || 'mongodb://localhost:27017/dev',  
    cloud: process.env.CLOUD_CODE_MAIN || __dirname + '/cloud/main.js',  
    appId: '<random text string>',  
    masterKey: '<random text string>',  
    clientKey: '<random text string>'  

Awesome! You’ve readied the Parse Server code locally. Now let’s get it to Heroku.

Setting Up Heroku

Alright, at this point you need a Heroku account. Go to and sign up for an account. Note your account username and password somewhere safe.

Note: You need to verify your account email address before you can use Heroku. Sign up, wait for the verification email to arrive, click the link, then sign back in to Heroku.



Next up, make sure the Heroku Toolbelt knows who you are. Type the following in Terminal:

$ heroku login

When Heroku asks for it, input your username and password.

Next, we’re going to deploy the local code of Parse Server to a Heroku instance. It’s incredibly easy…

First, make sure you’re still in the ~/heroku/parse-server-example directory with Terminal (or the directory where you cloned your Parse Server example code).

Then, type this on the command line:

$ heroku create

Heroku will now create an app for you, assign it a random name and add a Git “remote” to the repository. This is one of the powers of Heroku: you can deploy and update your app’s code with Git.

The output at the command line will be similar to this:

~/heroku/parse-server-example $ heroku create  
Creating app... done, stack is cedar-14 |

Next up, you need to add the recent code changes (for the App ID and Keys) to your local repository. You changed the file, indeed, but these changes also need to be tracked in the Git repository. Input the following two commands in Terminal.

$ git add index.js  
$ git commit -m "Changed configuration values"

The index.js file is now added to the local repository, but the source code change is not uploaded to the Heroku instance we created. We’ll do this now. You’ll upload your Parse Server example code (called pushing) to the Heroku instance you created with heroku create. Heroku will then deploy the code for you on the Heroku instance.

Type this in Terminal:

$ git push heroku master

If all goes OK, you’ll see a bunch of lines racing across your screen. If you dig a little deeper, you’ll see Heroku recognizes the NodeJS app, builds a whole bunch of dependencies (library code Parse Server uses), and then attempts to restart the app process (which doesn’t exist).

At this time, the Parse Server code now resides with Heroku, but our Parse Server app hasn’t started yet!

Next up, we need to set that environment variable that points to your MongoDB database instance. You’ll do that with the MongoDB URI. You can find it at the top of your mLab dashboard:

Heroku Dashboard: mLab URI

Heroku Dashboard: mLab URI

Copy your mLab URI to a text file and then replace <dbuser> and <dbpassword> with your own username paws and password.

Note: Don’t use your account username and password, but use the username and password you created for the paws database. If you followed this guide, the username should be paws and the password something you set.

Next, type in the following in Terminal on the command line (still in the same directory). Replace the mongodb://... part with your own MongoDB URI.

heroku config:set DATABASE_URI=mongodb://...

The entire command should look similar to this:

heroku config:set DATABASE_URI=mongodb://<dbuser>:<dbpassword>

You can verify the environment variable was set correctly by going to your Heroku Dashboard, clicking on the name of your instance (mine’s called powerful-dawn) and then clicking on the Settings tab. Then, click on Reveal Config Vars. If you’ve set the DATABASE_URI right, it should show up.

Config Vars

Config Vars

Alright, we’re almost there. Next up: starting the Heroku instance! In order to start the Heroku instance, type this on the command-line, still in the same directory:

heroku ps:scale web=1

And then:

heroku open

The first line starts a process for the Heroku app, and the second line opens your browser and shows the response from the Heroku app. If all went OK, it should say:

I dream of being a web site.

Awesome! Your Heroku instance is now complete.

Note: Normally, you’d manage your app’s processes with a Procfile. Also, you can see that “I dream of …” line show up in the file index.js. By the way, looking at the source code of parse-server-example you can’t help but notice it’s very small… Where’s all the source code? It’s in a dependency, the library is called parse-server and you can find it’s code at:

4. Configuring The “Paws” App

Yessss, no more command line! Next up, we’re going to connect the Paws iOS app with the new Heroku web service – your own Parse Server instance!

Start the Paws.xcworkspace in Xcode and open the AppDelegate.swift file. You’ve worked with this file before. Then, do this:

  • First, comment (or remove) the first code line of the method application:didFinishLaunchingWithOptions: by placing // at the beginning of the line.
  • Then, uncomment the comment block you created earlier a couple of lines down around the let config ... block.
  • Then, replace the ... for applicationId and clientKey with their respective values. You can find those values in index.js of parse-example-server, if you forgot them. You don’t have to set masterKey.
  • Finally, copy the URL of the web page that said I dream of being a web site.. It looks like this: https://[app instance name] Paste it for the server configuration in AppDelegate.swift. Make sure you type /parse at the end of the URL!

Make sure you’ve got the Swift syntax right (no spaces, single quotes) and double check you’ve correctly copied and pasted the configuration values. Check out the following screenshot if didn’t get it right.

Xcode: New Configuration

Xcode: New Configuration

Next up, the piece de resistance, let’s see if it actually worked! Run the app with Command-R on iPhone Simulator or your own device. It’ll probably take 5–6 seconds before you’re seeing cat pictures after the app starts, but if all went OK you should see them.

Didn’t work? Bummer! Ask for help in the comments.

Did it work? AWESOME! YOU ROCK!

Aw yisss... cat pictures!

Aw yisss… cat pictures!

But… the result is the same as when you’d use the original Parse, right? I mean, that’s the point, but how can you make sure the app uses the right back-end?

OK, testing that is easy. Note down the number of votes the first image has, and what the name of the cat is. For instance, Azrael and 6 votes.

Then, double tap the cat picture. A cat paw should pop up (cute!) and the vote count should increase to 7 votes.

Then, open your mLab Dashboard and click the Connections tab for your MongoDB database.

Then, click the Cat collection. A rudimentary overview of the cat data should show up. In the list, find the Azrael cat (you can use Command-F). Locate the votes key for the item and check what the vote count is. Is it 7? Awesome, it works!

Check The Data

Check The Data


Pfew… that was quite some work! Did it all work out? Well done. You’ve just successfully migrated from Parse to Parse Server on Heroku and mLab!

Did you like this coding guide? Make sure to check out the Pro Course, a solid online course that shows you how you can build and market your own apps.

What’s next? Now you actually have to worry about indices, database size, and scaling up your back-end. Another day, perhaps…

Parse has been a landmark for a large amount of app makers around the world and it will be missed. I reckon the migration is an education for many app makers, because it forces them to start thinking about back-end portability and reliability, while at the same time making them experience what it’s like to run your own back-end.

You could argue about the effect of acquisitions of the Internet Big Five (Amazon, Google, Facebook, Microsoft and Apple) of small high-tech companies on the internet and app ecosystem as a whole. The “for app makers, by app makers” seems to fade quickly in the face of multi-million dollar acquisitions. Facebook is focusing on mobile advertisement and the next big thing: virtual reality, and left an in 2013 risky acquisition (almost) for dead.

Perhaps now a decade starts in which the authentic Platform-as-a-Service underdog will remain in competition with the Big Five, instead of being incorporated by it.

I remember trying to get a spare Pentium II to run a web service 15 years ago. A lot has changed since then, especially the speed of change. With one thought, I’m a big fan of done-for-you services because they aid rapid prototyping. On another thought, I’m also a fan of tinkering and showing my peers how to tinker with technology. Maybe we got a little lazy, because the tools we relied on got too easy to use.

Your contingency for a change in technology, and its reliability, is to never unlearn how to tinker.

Further Reading

There’s much more to find out!

Join 11.000+ app developers and marketers
  • Every Monday: get curated app marketing news, resources, tools and goodies in your inbox
  • Grow your app's userbase with the latest App Store Optimization and app marketing strategies
  • FREE: Get the free step-by-step Get Started With Your App Idea guide to set yourself up for App Store success!
Yes, Sign Me Up!

Popular Posts

Written By: Reinder de Vries

Reinder de Vries is an indie app maker who teaches aspiring app developers and marketers how to build their own apps at He has developed 50+ apps and his code is used by millions of users all over the globe. When he’s not coding, he enjoys strong espresso and traveling.

Get instant access to The Step-by-Step Guide: Get Started With Your App Idea

(PLUS: see the tool we use to save a ton on back-end coding)


Comments & Thoughts

  • John Thomas

    Thanks for the well documented tutorial.

    I had an issue at this point using Heroku’s Free service…
    heroic ps:scale web=1
    Skipping this step seemed to work.

  • Thanks! Did you already have a dyno running, or a Procfile present? “heroku ps” just starts up one web process. (You’ve got a typo there, it’s “heroku”, but I assume that’s only just the comment)

  • Moath

    Thnx for the tutorial , it worked with me for a more complex database .
    I needed to add `fileKey: ‘filekey’,` to retrieve images since am using PFFile objects, but I think I should move the Assets as well !! do u have any idea what should be done here ?! , thnx alot

  • Josh Robbins

    Your Awesome!!!! So Easy To Follow!

  • Thanks, Josh!

  • Yes, files should move right over to the new MongoDB. They’re just stored as “blobs”. Saving files this way isn’t good practice though, you quickly end up with a huge database.

    My recommendation is to move the files over to a file server / file service like Amazon S3. You’d “disconnect” them from the database, instead of saving the file contents you’d save an Amazon S3 URL (or HTTPS URL). Amazon is relatively cheap, has an iOS/Android SDK and offers features like authentication / access control (yes, for images). Of course, there are alternatives, like Azure.

    Good luck!

  • Mehdi Abderezai

    Great tutorial,
    I was able to migrate my parse data and followed your basic steps. But still don’t know how to add my custom cloud code I have, and the many files (tho I’m guessing its just a matter of copying the files to the cloud folder. Additionally, I use Stripe and Mailgun, and webhooks! … any help would be much appreciated.

  • Daniyaal Hadzami

    This is great tutorial!

    I have an issue in “pod update part”. Instead of downloading dependencies, I got this results as shown below. I’m following the steps carefully and it still doesn’t work. What do you think my mistake was at?

    Thank you.

  • Daniyaal Hadzami

    This is an awesome tutorial!
    But anyway, I got this issue below. The “$ git push heroku master” does not seem to work out. What do you think my mistake was at?
    Thank you so much in advance!

  • Mehdi Abderezai

    Did you install the heroku toolbelt? check with: heroku –version

  • Mehdi is right, check that you have installed the Toolbelt and created the heroku remote by executing “heroku create” in the repository directory (~/heroku/parse-server-example). Good luck!

  • Did you update to the latest version of the Parse SDK for Android? See if you can track down the line of the error (so you can see its code) with a debugger, and inspect the actual contents of the JSON. “Bad response” usually means there’s a syntax error in the JSON, the JSON didn’t contain everything that was expected, or there’s a server error. Good luck!

  • You can place them in the /cloud directory. Unfortunately, you can’t use Parse’s native Cloud Modules, so you’ll probably need to rewrite part of your code to work with the (official) NodeJS packages. Read about it here, under “3. Cloud Code”:

    My guess is the function calls etc. don’t differ greatly, but their implementation and output does. Make sure you test your code thoroughly.

    I’m not sure about webhooks. Are you calling them from Parse, i.e. Parse trigger => webhook gets called? You could see if you can hook into Parse Server and POST the webhooks yourself. You could also look into Zapier (they now support custom JS).

    Good luck!

  • Valsamis Elmaliotis

    i get an “application error” when i try to open the app

  • Could you copy and paste the entire error from the Debugger Window in a reply? Thanks!

  • Valsamis Elmaliotis

    Valsamiss-MacBook-Pro:parse-server-example Valsamis$ heroku logs

    2016-02-02T09:48:01.200416+00:00 app[web.1]: npm ERR! Exit status 1

    2016-02-02T09:48:01.200738+00:00 app[web.1]: npm ERR!

    2016-02-02T09:48:01.201366+00:00 app[web.1]: npm ERR! Make sure you have the latest version of node.js and npm installed.

    2016-02-02T09:48:01.201047+00:00 app[web.1]: npm ERR! Failed at the [email protected] start script ‘node index.js’.

    2016-02-02T09:48:01.201638+00:00 app[web.1]: npm ERR! If you do, this is most likely a problem with the parse-server-example package,

    2016-02-02T09:48:01.202264+00:00 app[web.1]: npm ERR! Tell the author that this fails on your system:

    2016-02-02T09:48:01.201969+00:00 app[web.1]: npm ERR! not with npm itself.

    2016-02-02T09:48:01.202806+00:00 app[web.1]: npm ERR! node index.js

    2016-02-02T09:48:01.203312+00:00 app[web.1]: npm ERR! You can get their info via:

    2016-02-02T09:48:01.203882+00:00 app[web.1]: npm ERR! There is likely additional logging output above.

    2016-02-02T09:48:01.207741+00:00 app[web.1]:

    2016-02-02T09:48:01.203618+00:00 app[web.1]: npm ERR! npm owner ls parse-server-example

    2016-02-02T09:48:01.197118+00:00 app[web.1]: npm ERR! Linux 3.13.0-71-generic

    2016-02-02T09:48:01.208213+00:00 app[web.1]: npm ERR! Please include the following file with any support request:

    2016-02-02T09:48:01.208515+00:00 app[web.1]: npm ERR! /app/npm-debug.log

    2016-02-02T09:48:02.028901+00:00 heroku[web.1]: Process exited with status 1

    2016-02-02T09:48:02.035787+00:00 heroku[web.1]: State changed from starting to crashed

    2016-02-02T09:54:25.437530+00:00 heroku[web.1]: Starting process with command `npm start`

    2016-02-02T09:54:28.129722+00:00 app[web.1]:

    2016-02-02T09:54:28.129744+00:00 app[web.1]: > [email protected] start /app

    2016-02-02T09:54:28.129746+00:00 app[web.1]: > node index.js

    2016-02-02T09:54:28.129747+00:00 app[web.1]:

    2016-02-02T09:54:28.210187+00:00 app[web.1]: /app/index.js:16

    2016-02-02T09:54:28.210191+00:00 app[web.1]: appId: ‘x74ZwkkXZrgRGBskTscA9OP9uKFegta6pP1KrNDj’,

    2016-02-02T09:54:28.225140+00:00 app[web.1]: npm ERR! Linux 3.13.0-71-generic

    2016-02-02T09:54:28.210196+00:00 app[web.1]: ^

    2016-02-02T09:54:28.210197+00:00 app[web.1]:

    2016-02-02T09:54:28.225578+00:00 app[web.1]: npm ERR! argv “/app/.heroku/node/bin/node” “/app/.heroku/node/bin/npm” “start”

    2016-02-02T09:54:28.225820+00:00 app[web.1]: npm ERR! node v5.4.0

    2016-02-02T09:54:28.210197+00:00 app[web.1]: SyntaxError: Unexpected token ILLEGAL

    2016-02-02T09:54:28.210198+00:00 app[web.1]: at exports.runInThisContext (vm.js:53:16)

    2016-02-02T09:54:28.226662+00:00 app[web.1]: npm ERR! npm v3.3.12

    2016-02-02T09:54:28.226877+00:00 app[web.1]: npm ERR! code ELIFECYCLE

    2016-02-02T09:54:28.210199+00:00 app[web.1]: at Module._compile (module.js:374:25)

    2016-02-02T09:54:28.210200+00:00 app[web.1]: at Module.load (module.js:344:32)

    2016-02-02T09:54:28.210200+00:00 app[web.1]: at Object.Module._extensions..js (module.js:405:10)

    2016-02-02T09:54:28.210202+00:00 app[web.1]: at Function.Module.runMain (module.js:430:10)

    2016-02-02T09:54:28.227057+00:00 app[web.1]: npm ERR! [email protected] start: `node index.js`

    2016-02-02T09:54:28.227213+00:00 app[web.1]: npm ERR! Exit status 1

    2016-02-02T09:54:28.210201+00:00 app[web.1]: at Function.Module._load (module.js:301:12)

    2016-02-02T09:54:28.227394+00:00 app[web.1]: npm ERR!

    2016-02-02T09:54:28.227588+00:00 app[web.1]: npm ERR! Failed at the [email protected] start script ‘node index.js’.

    2016-02-02T09:54:28.219135+00:00 app[web.1]:

    2016-02-02T09:54:28.227775+00:00 app[web.1]: npm ERR! Make sure you have the latest version of node.js and npm installed.

    2016-02-02T09:54:28.210202+00:00 app[web.1]: at startup (node.js:141:18)

    2016-02-02T09:54:28.210203+00:00 app[web.1]: at node.js:1003:3

    2016-02-02T09:54:28.227962+00:00 app[web.1]: npm ERR! If you do, this is most likely a problem with the parse-server-example package,

    2016-02-02T09:54:28.228114+00:00 app[web.1]: npm ERR! not with npm itself.

    2016-02-02T09:54:28.228304+00:00 app[web.1]: npm ERR! Tell the author that this fails on your system:

    2016-02-02T09:54:28.228486+00:00 app[web.1]: npm ERR! node index.js

    2016-02-02T09:54:28.228666+00:00 app[web.1]: npm ERR! You can get their info via:

    2016-02-02T09:54:28.228937+00:00 app[web.1]: npm ERR! npm owner ls parse-server-example

    2016-02-02T09:54:28.229103+00:00 app[web.1]: npm ERR! There is likely additional logging output above.

    2016-02-02T09:54:28.231940+00:00 app[web.1]:

    2016-02-02T09:54:28.232230+00:00 app[web.1]: npm ERR! Please include the following file with any support request:

    2016-02-02T09:54:28.232383+00:00 app[web.1]: npm ERR! /app/npm-debug.log

    2016-02-02T09:54:28.924545+00:00 heroku[web.1]: State changed from starting to crashed

    2016-02-02T09:54:28.905726+00:00 heroku[web.1]: Process exited with status 1

    2016-02-02T09:54:24.122529+00:00 heroku[web.1]: State changed from crashed to starting

    2016-02-02T10:16:43.998129+00:00 heroku[web.1]: State changed from crashed to starting

    2016-02-02T10:16:46.511459+00:00 heroku[web.1]: Starting process with command `npm start`

    2016-02-02T10:16:50.064394+00:00 app[web.1]:

    2016-02-02T10:16:50.064409+00:00 app[web.1]: > [email protected] start /app

    2016-02-02T10:16:50.064410+00:00 app[web.1]: > node index.js

    2016-02-02T10:16:50.064410+00:00 app[web.1]:

    2016-02-02T10:16:50.310294+00:00 app[web.1]: appId: ‘x74ZwkkXZrgRGBskTscA9OP9uKFegta6pP1KrNDj’,

    2016-02-02T10:16:50.310295+00:00 app[web.1]: ^

    2016-02-02T10:16:50.310288+00:00 app[web.1]: /app/index.js:16

    2016-02-02T10:16:50.310296+00:00 app[web.1]:

    2016-02-02T10:16:50.310306+00:00 app[web.1]: at node.js:1003:3

    2016-02-02T10:16:50.310301+00:00 app[web.1]: SyntaxError: Unexpected token ILLEGAL

    2016-02-02T10:16:50.310304+00:00 app[web.1]: at Function.Module._load (module.js:301:12)

    2016-02-02T10:16:50.310305+00:00 app[web.1]: at startup (node.js:141:18)

    2016-02-02T10:16:50.310302+00:00 app[web.1]: at exports.runInThisContext (vm.js:53:16)

    2016-02-02T10:16:50.310302+00:00 app[web.1]: at Module._compile (module.js:374:25)

    2016-02-02T10:16:50.310303+00:00 app[web.1]: at Object.Module._extensions..js (module.js:405:10)

    2016-02-02T10:16:50.310303+00:00 app[web.1]: at Module.load (module.js:344:32)

    2016-02-02T10:16:50.310305+00:00 app[web.1]: at Function.Module.runMain (module.js:430:10)

    2016-02-02T10:16:50.344960+00:00 app[web.1]:

    2016-02-02T10:16:50.352913+00:00 app[web.1]: npm ERR! Linux 3.13.0-71-generic

    2016-02-02T10:16:50.352916+00:00 app[web.1]: npm ERR! argv “/app/.heroku/node/bin/node” “/app/.heroku/node/bin/npm” “start”

    2016-02-02T10:16:50.352917+00:00 app[web.1]: npm ERR! node v5.4.0

    2016-02-02T10:16:50.352918+00:00 app[web.1]: npm ERR! npm v3.3.12

    2016-02-02T10:16:50.352919+00:00 app[web.1]: npm ERR! code ELIFECYCLE

    2016-02-02T10:16:50.352919+00:00 app[web.1]: npm ERR! [email protected] start: `node index.js`

    2016-02-02T10:16:50.352920+00:00 app[web.1]: npm ERR! Exit status 1

    2016-02-02T10:16:50.352921+00:00 app[web.1]: npm ERR!

    2016-02-02T10:16:50.352922+00:00 app[web.1]: npm ERR! Failed at the [email protected] start script ‘node index.js’.

    2016-02-02T10:16:50.352922+00:00 app[web.1]: npm ERR! Make sure you have the latest version of node.js and npm installed.

    2016-02-02T10:16:50.352924+00:00 app[web.1]: npm ERR! If you do, this is most likely a problem with the parse-server-example package,

    2016-02-02T10:16:50.352924+00:00 app[web.1]: npm ERR! not with npm itself.

    2016-02-02T10:16:50.352926+00:00 app[web.1]: npm ERR! You can get their info via:

    2016-02-02T10:16:50.352926+00:00 app[web.1]: npm ERR! node index.js

    2016-02-02T10:16:50.352928+00:00 app[web.1]: npm ERR! There is likely additional logging output above.

    2016-02-02T10:16:50.352925+00:00 app[web.1]: npm ERR! Tell the author that this fails on your system:

    2016-02-02T10:16:50.352927+00:00 app[web.1]: npm ERR! npm owner ls parse-server-example

    2016-02-02T10:16:50.371350+00:00 app[web.1]:

    2016-02-02T10:16:50.371352+00:00 app[web.1]: npm ERR! Please include the following file with any support request:

    2016-02-02T10:16:50.371353+00:00 app[web.1]: npm ERR! /app/npm-debug.log

    2016-02-02T10:16:51.341331+00:00 heroku[web.1]: Process exited with status 1

    2016-02-02T10:16:51.358886+00:00 heroku[web.1]: State changed from starting to crashed

    Valsamiss-MacBook-Pro:parse-server-example Valsamis$

  • Daniyaal Hadzami

    Thank you so much!
    It works! I forgot to create the heroku remote in the proper repository directory. Thanks !

  • Vicky Arora

    I am stuck at Parse screen showing the progress. I cannot see any progress and what I can see is the progress stuck at the image as attached below. Can you please help me what I can do to solve this?

  • Jackmarrone

    Hey! I followed everything but i’m stuck when I launch Heroku open.. i can’t even dream of being website… 🙁
    anyways i get this. Any help?. Thank you

  • Are you migrating your own app or the Paws app from the code guide? The migration can take a while.

  • When you said “application error” I assumed you saw an error in Xcode when trying to run the iOS app. You now have pasted output from the Terminal.

    It appears your NodeJS / npm is outdated. Make sure you update to the latest versions.

  • Valsamis Elmaliotis

    i am new to this from where i update the nodjs? locally? isn’t this upload ti to heroku? should i update nodjs to heroku? do you know the procedure? i will pay for a detailed guide

  • Vicky Arora

    I am using Paws app. I wanted to test this, before I do this on my own app.

  • OK. It can take a while, I’m not sure how long. Are you sure you input the right MongoDB URI?

  • Follow the guide step by step. You’re not supposed to run Parse Server locally (at least, according to my code guide), but instead upload and deploy it on Heroku. You don’t have to pay for a detailed guide, it’s already right here, on your screen.

  • Vicky Arora

    Yes, I did. If I enter a wrong ID / Password it wont let me proceed. So if it proceeding to the progress screen than I am assuming that everything was entered correctly. Its been 2-3 hrs now. I haven’t seen any progress.

  • Daniyaal Hadzami

    problem solved! Thank you!

  • You can check in the MongoLab dashboard if data is coming in (“Collections” tab), otherwise I’d stop the migration and try again. You can imagine many developers are trying to migrate their data, so it could also just be a busy queue.

  • Vicky Arora

    I did check that, the collection tab has no data. I will wait and see if something happens today, if not, will retry everything again.

  • OK. Check if “index.js” in the repository contains a route that says “I dream of being a website”. The line starts with “app.get”. If not, you may have accidentally cloned “parse-server” instead of “parse-server-example”. Additionally, you could run “heroku logs” in the repository directory (~/heroku/parse-server-example) to check for errors. Good luck!

  • You’re welcome! Glad it worked out.

  • Valsamis Elmaliotis

    is this good or bad?
    [master 21f6734] Changed configouration values

    Committer: Valsamis Elmaliotis

    Your name and email address were configured automatically based

    on your username and hostname. Please check that they are accurate.

    You can suppress this message by setting them explicitly. Run the

    following command and follow the instructions in your editor to edit

    your configuration file:

    git config –global –edit

    After doing this, you may fix the identity used for this commit with:

    git commit –amend –reset-author

    1 file changed, 3 insertions(+), 2 deletions(-)

  • This just means you didn’t set a Git username. The message says it set the username automatically for you based on your email address and host name. Essentially, it has nothing to do with migrating to Heroku. The last line appears to be OK, it means you updated the “index.js” code. Continue where you left off, probably somewhere around “Setting Up Heroku”. Good luck!

  • Jackmarrone

    I do have parse example installed. Here’s my log. I really don’t get why this isn’t working

    2016-02-02T12:38:10.624022+00:00 heroku[web.1]: State changed from crashed to starting

    2016-02-02T12:38:12.095941+00:00 heroku[web.1]: Starting process with command `npm start`

    2016-02-02T12:38:14.396995+00:00 app[web.1]:

    2016-02-02T12:38:14.397057+00:00 app[web.1]: > node index.js

    2016-02-02T12:38:14.397055+00:00 app[web.1]: > [email protected] start /app

    2016-02-02T12:38:14.464334+00:00 app[web.1]: /app/index.js:18

    2016-02-02T12:38:14.397057+00:00 app[web.1]:

    2016-02-02T12:38:14.464338+00:00 app[web.1]: clientKey: ‘ip***************************************************’

    2016-02-02T12:38:14.464339+00:00 app[web.1]: ^^^^^^^^^

    2016-02-02T12:38:14.464341+00:00 app[web.1]: SyntaxError: Unexpected identifier

    2016-02-02T12:38:14.464340+00:00 app[web.1]:

    2016-02-02T12:38:14.464341+00:00 app[web.1]: at exports.runInThisContext (vm.js:53:16)

    2016-02-02T12:38:14.464342+00:00 app[web.1]: at Module._compile (module.js:374:25)

    2016-02-02T12:38:14.464343+00:00 app[web.1]: at Object.Module._extensions..js (module.js:405:10)

    2016-02-02T12:38:14.464343+00:00 app[web.1]: at Module.load (module.js:344:32)

    2016-02-02T12:38:14.464344+00:00 app[web.1]: at Function.Module._load (module.js:301:12)

    2016-02-02T12:38:14.464344+00:00 app[web.1]: at Function.Module.runMain (module.js:430:10)

    2016-02-02T12:38:14.464345+00:00 app[web.1]: at startup (node.js:141:18)

    2016-02-02T12:38:14.471736+00:00 app[web.1]:

    2016-02-02T12:38:14.464350+00:00 app[web.1]: at node.js:1003:3

    2016-02-02T12:38:14.476641+00:00 app[web.1]: npm ERR! argv “/app/.heroku/node/bin/node” “/app/.heroku/node/bin/npm” “start”

    2016-02-02T12:38:14.476327+00:00 app[web.1]: npm ERR! Linux 3.13.0-71-generic

    2016-02-02T12:38:14.476789+00:00 app[web.1]: npm ERR! node v5.4.0

    2016-02-02T12:38:14.477416+00:00 app[web.1]: npm ERR! npm v3.3.12

    2016-02-02T12:38:14.477530+00:00 app[web.1]: npm ERR! code ELIFECYCLE

    2016-02-02T12:38:14.477638+00:00 app[web.1]: npm ERR! [email protected] start: `node index.js`

    2016-02-02T12:38:14.477741+00:00 app[web.1]: npm ERR! Exit status 1

    2016-02-02T12:38:14.477858+00:00 app[web.1]: npm ERR!

    2016-02-02T12:38:14.477965+00:00 app[web.1]: npm ERR! Failed at the [email protected] start script ‘node index.js’.

    2016-02-02T12:38:14.478074+00:00 app[web.1]: npm ERR! Make sure you have the latest version of node.js and npm installed.

    2016-02-02T12:38:14.478263+00:00 app[web.1]: npm ERR! not with npm itself.

    2016-02-02T12:38:14.478165+00:00 app[web.1]: npm ERR! If you do, this is most likely a problem with the parse-server-example package,

    2016-02-02T12:38:14.478415+00:00 app[web.1]: npm ERR! node index.js

    2016-02-02T12:38:14.478401+00:00 app[web.1]: npm ERR! Tell the author that this fails on your system:

    2016-02-02T12:38:14.478623+00:00 app[web.1]: npm ERR! npm owner ls parse-server-example

    2016-02-02T12:38:14.478502+00:00 app[web.1]: npm ERR! You can get their info via:

    2016-02-02T12:38:14.478703+00:00 app[web.1]: npm ERR! There is likely additional logging output above.

    2016-02-02T12:38:14.480911+00:00 app[web.1]:

    2016-02-02T12:38:14.481066+00:00 app[web.1]: npm ERR! Please include the following file with any support request:

    2016-02-02T12:38:14.481283+00:00 app[web.1]: npm ERR! /app/npm-debug.log

  • OK. Could you check the syntax of “index.js” at the lines where you set the Application ID and Client Key? Make sure you enclose the strings in single quotes, and all dictionary items end with a comma (except for the last line). Your logs show there’s an error around “clientKey”.

  • Valsamis, could you check the syntax of “index.js” at the lines where you set the Application ID and Client Key? Make sure you enclose the strings in single quotes, and all dictionary items end with a comma (except for the last line).

  • Jackmarrone

    I found my problem. I was missing the “,” before the clientKey. but once I had changed it I needed to run again the

    $ git add index.js
    $ git commit -m “Changed configuration values”.

    I now get the dream of a website msg.
    Thank you For your help

  • Peter

    Did you find a solution to this problem?

  • Mamoun MK

    Thank you for this tuto it’s work well with me !
    I have occurred some complication when loading Profile image _User from another collection “Products”, but I don’t know if MangoLab don’t make a connexion between two collection _User and Products ? Because Products Images load without problem… Can you help me please (Swift iOS)

  • Did you set up a pointer in the original Parse (not in Parse Server)?

  • Mamoun MK


  • Mamoun MK

    Sorry I mean this image lol

  • Ry110891

    Thank you for the tutorial it worked well for me. The one problem for me are PFFiles. Images are not loading and I am getting a 403 error message.

  • Did you set the fileKey in index.js? Pointers should migrate without problems. I really can’t help you any further, because what you’re doing is beyond the scope of the tutorial. Your best bet would be to open an issue ticket in parse-server on GitHub, or ask a question on StackOverflow.

  • Mamoun, you need to set the “fileKey” in index.js, like this:

    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 || 'myMasterKey',
    fileKey: ''

  • You need to set the “fileKey” config value, like this:

    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 || 'myMasterKey',
    fileKey: ''

    You can find the key in your Parse Dashboard.

  • You probably have to wait before the issue makes it into an official release. You can update the code by executing “git pull” in the repository directory.

  • Mehdi Abderezai

    I’m a little unsure of what the Profile actually does in the context of this tutorial. Do we even have one?

  • Vicky Arora

    It finally worked after 12hrs!!! For such a small data it took 12hrs. And there is one more interesting thing, I can see that in the collection, there is a “dummy” row which for some strange reason has 3000+ documents. I am using the same Paws app, nothing changed in documents from my side.

  • That’s really weird! It probably took so long because the queue was busy, the data itself isn’t that big (even with 3000+ extra rows). If you’re sure the data isn’t yours, you could check and/or file a bug report with Parse.

  • No, we don’t have a Procfile. Instead, we just start one web process manually. A Procfile is a configuration file that defines what kinds of processes you want to run, for instance if you have 2 “foreground” web processes, and 1 background worker process.

    When Heroku deploys your application (git push), it’ll read the Procfile and (re)start the appropriate processes. It’s one of the powers of Heroku: automatic and scripted deployment.

  • Jackmarrone

    Hey! would be cool if you added the code to add the new config to android as well. any chance? thanx

  • For Android, that would be similar to:

    Parse.initialize(new Parse.Configuration.Builder(myContext)


  • Jackmarrone

    Tried it but it’s not writing to db.
    going to my (which is what I’ve placed in my server url key in android app) gets my this error {“error”:”unauthorised”}.. bummer

  • Did you set the Client Key and the Application ID correctly?

  • Jackmarrone


    This is driving me crazy….

    in terminal a curl call works fine and i’m able to query my db
    if i leave my old parse.initialize(“key,key”)
    that writes to both & mongoDB from my app. Any clue?

  • Jackmarrone

    I figure it out! I looked up if a simple app on iOS would do the trick and it worked. so i’ve googled it around and what i was missing was a /

    Android users don’t forget the “/” after “parse” in your server url!!!!

    Parse.initialize(new Parse.Configuration.Builder(getBaseContext())

    quick question, is it right that parse db on is still updating what i do on mongoDB?

  • Changes that are made on the original Parse will be sent to your MongoDB, because you’ve set the MongoDB as the “destination” database during the migration. Active users of your app will still use the original Parse endpoint, but that Parse will talk to the MongoDB database. Check out the diagram at the top of the article, especially the intermediary step.

  • Nikita Kerd

    Big thanks for the tutorial, it is great! However, i can’t get info from the server 🙂 Any idea, what could be the reason for [Error]: {“code”:1,”message”:”Internal server error.”} (Code: 1, Version: 1.12.0) ?

  • Thanks, glad you like it! Good thing you solved that error. You can also get logs when executing “heroku logs” in your repository directory.

  • Mehdi Abderezai

    How do you add classes and set class permissions without the dashboard? Or we are assuming that the parse team would make the dashbaord UI built into the parse server code eventually?

  • Lisa B

    This tutorial is SO helpful! I can’t thank you enough! Could I ask you to also do a tutorial on migrating to an image management system (like Cloudinary, which is what Parse suggests) and to a new Push Notification client? I will pay you with good karma vibes….

  • Morgan Le Gal

    Same problem here… It’s been going on since 15hours. My second try.

  • Chuong Lam

    I got an error when trying to migrate parse db to mongolab. I used mongodb:// URL in the input field and click Begin the migration. Then it displayed:
    “We strongly suggest you enable SSL on your database and use the URL option ‘ssl=true’.
    Latency to your database is higher than 20ms, this will likely result in poor performance.”
    Please help

  • You should be able to continue after that warning. SSL is a paid option, so I didn’t include it in the coding guide. Keep in mind that if you’re migrating sensitive data, you should enable SSL ($80). The latency could be because of a high load on the MongoLab shared server you’re on, or high load on Parse’s migration servers. The US East region is geographically closest to Parse, so that can’t be a problem.

  • Thanks! I’ll add it to the list.

  • No, that’s for the “” that contains a directory with .bson / .json files. You only need this if you don’t have a Parse account. If you do, just use Parse’s migration feature.

  • You can do that in the scheme collection of MongoDB, but it’s implementation is beyond the scope of this code guide. I’m suspecting Parse will eventually open source its UI, but in the meantime there’s plenty of MongoDB admin alternatives like AdminMongo (Node) and MongoHub (OS X).

  • Parse is probably busy migrating 500.000 developers. ETA 4 months…

  • Chuong Lam

    Thanks so much.

  • Lisa B

    Great! One question – not sure if you know this, but Parse seems to be storing PFFiles in an Amazon S3 bucket (as far as I can tell). When I migrate to mongoLab there are links to my PFFiles but they aren’t stored there. Will we eventually have to create our own storage for these files or will Parse continue to hold them for us indefinitely…? I suppose I’m a bit confused on how this works…

  • Julien Pires

    Thanks for the tutorial. I followed every steps and I can’t get it work when I try to query with JS SDK. I receive a 403 error with following content “{code: undefined, message: “unauthorized”}”. I set every key correctly (AppKey, MasterKey and ClientKey) in the index.js file. I used the JS example here : by modifying the serverURL, the key in Intialize method and class name.

  • You’re right, old files will stay in Parse’s S3, new files are stored in Mongo. It’s a far from ideal situation. This thread (and comment) explains the situation and its progression better:

    Keep an eye on that! My suggestion is to move over to your own S3, but I’m not sure if Parse will provide a solution for you to migrate your files.

  • I can’t go into detail about the JavaScript SDK because it’s beyond the scope of this code guide. My advice would be to double check your keys, both in Parse Server and your own client-side JS implementation. Perhaps you do need to specifically set all keys at the client-side JS code. Check threads on StackOverflow and the GitHub repo issue page.

  • BK

    When I try to update the local repository with:

    $ git add index.js

    I get an error saying:

    “fatal: pathspec ‘index.js’ did not match any files”

    Any idea what’s going on?

  • Chuong Lam

    I tried opening https://[app instance name] and it displays ‘{“error”:”unauthorized”}’, would you help please?

  • Does it work in your app? If you open that URL in your browser, it doesn’t work, because your browser isn’t sending the required Application ID and Client Key with the HTTP request.

    You can either remove the “/parse” part when opening the Heroku app URL in your browser, or continue and make sure you’re setting the tokens right.

  • Did you update the Parse SDK to the latest version?

    BTW, how did you solve the Git pathspec error? My guess was that index.js wasn’t under version control, i.e. you didn’t “heroku create”.

  • BOSE

    ERROR: The database name ‘paws’ is currently not available. Please try a different name.

    i am getting this error while creating a new MongoDB

  • BOSE

    *ERROR: The database name ‘paws’ is currently not available. Please try a different name.*
    I am getting this error while creating a new MongoDB, any recommendations?
    PS: i am total noob to parse, just got into android programming and wanted to learn parse.

  • BK

    Sorry, I’ve just fixed both problems.

    You were right; I need to update the Parse SDK.

    And as for the pathspec error, I wasn’t in the correct directory.

    Thanks for the tutorial. I was feeling pretty overwhelmed about all of this, but I’m good to go now.

  • BK

    I had the exact same problem as you. Just fixed it. I accidentally put a space after each of my keys in the index.js file. I was 100% certain that I typed it in correctly, but alas I was wrong. Take a look at your index.js file.

  • Awesome! Well done 🙂

  • Make sure you’ve selected the right plan, as per the coding guide. You need Single Node -> Sandbox, but currently you’re looking at replicated clusters.

    If that doesn’t help, pick a different database name (and don’t forget to update the code / console commands to reflect the right name).

  • MR

    hi.thanks for the tutorial..I need help.. i got an error when I try to post data via the cmd on Mac.

    my code :
    $ curl -X POST -H “X-Parse-Application-Id: MCb856fCHT3v88hUvB66CFBOR1iCbP7rpHqDf3Pq” -H “Content-Type: application/json” -d ‘{“name”:”secondname”}’

    the result : {“error”:”unauthorized”}


  • Make sure to include your Master Key. See the example on:

  • Peter

    How do you add the rest of the parse-server source code to the Heroku instance? I completed the parse-server-example and have a working application but there are some errors I’m guessing due to the missing source code.

  • The parse-server package is added as a dependency to parse-server-example. You can probably see it flying by when doing a “git push heroku master”, when Heroku builds the entire app. Are you seeing errors at Heroku (“heroku logs” in repo directory) or locally? Follow the steps here to install parse-server-example locally:

  • Peter

    The ‘includeKey:’ in my queries is not returning the object data, only the objectId. I,m not finding any errors in my GET logs. Also, I’m getting a ‘[Error]: Can’t download a file that doesn’t exist on the server or locally.’

  • Chuong Lam

    Hi Reinder and BK,
    I can make sure that my keys in index.js file is correct. Then I use my javascript to query a list of objects, the request returns an error message “unauthorized” although I initialized my parse like this:
    Parse.initialize(“my_app_key”, “my_client_key”);
    Parse.serverURL = ‘my_url’ (with the ‘/parse’);
    should I have to to change my databaseUri in my index.js ?

  • MR

    thank you !

  • Could you tell me the steps that lead to that error, and what you’re trying to accomplish?

  • Try to also include the Master Key in your client-side JavaScript code.

  • Are you deliberately installing your data on a cluster of MongoDB databases? I’m not sure how Parse Server deals with this. Your best bet is to check the Issues on GitHub for Parse Server, or ask a question StackOverflow.

  • tamer

    Hello Reinder

    am beginning to migrate my app but i have a weird problem that the migration process stuck when it’is in the last stage “verify” please see the attachment .


  • I’m not sure what’s causing this. Is there a way you can manually verify your data and approve the migration?

  • tamer


    How i can do that can you help me please ?


  • Did the data you migrated end up in the new MongoDB database? You can check that with MongoLab. If the migration is complete and all data is OK, you can simply leave the migration for what it is.

  • MR

    hello… i didn’t change the code of parse-server-example and i write my cloudcode in ‘main.js’ inside the folder ‘cloud’ of parse-server-example but the cloud code doesn’t work when i do the migration!!! Any ideas??
    the code :
    var api = new ParseServer({
    databaseURI: databaseUri || ‘mongodb://localhost:27017/dev’,
    cloud: process.env.CLOUD_CODE_MAIN || __dirname + ‘cloud/main.js’,

  • Migrating Cloud Code is beyond the scope of this code guide, so I can’t help you with it. Your best bet would be to ask a question on StackOverflow, or comment in the Issues section of parse-server on GitHub. Keep in mind that your Cloud Code has nothing to do with migrating your data from Parse to MongoLab, but instead relies on the functioning and the code of your parse-server-example app on Heroku.

  • Rob Wright

    On this page, Parse requires failIndexKeyTooLong=false in Mongodb. How are you setting that parameter on the free tier at Mongolab? I didn’t think that was possible without a Dedicated Cluster.

  • You best check with MongoLab themselves, but my guess is you’re right. failIndexKeyTooLong is a global setting for Mongo, which means you need to restart the Mongo process and you probably can’t do that on the Shared DB plan.

  • Rob Wright


  • Mehdi Abderezai

    Hi MR,
    I have started migrating my cloud code and I it could be hard or easy depending on how complicated your cloud code is. Few things you need to do:

    1) make sure you are able to do heroku local builds with the right Node version.

    2) go through your code and comment out everything, you want to start introducing your code in parts and make sure it compiles at each step.

    3) install the node modules for each service that you use. If you use stripe/mailgun or any other package, add them in your package.json file and run npm install. Then include them in your main.js file with the require(‘packageName’). Hopefuly you know enough node/js and that made sense.

    4)The cloud server uses Express.js version 4.2 and a runs Express version 2.0 or 3.0 but not 4.0. If you use any middlewear (I used basic authentication) then you need to change it to the proper Express 4.0 syntax/methodology.

    5) there is no support for cloud jobs, so rename all your *.job functions to *.define and comment properly so you can come back to them. If you did not use cloud jobs then don’t worry.

    6) If you did use cloud jobs, now you need to setup a heroku worker/scheduler/something to run those old *.job (now *.define) calls at the proper time intervals you had.

    I’ve only made it to step 5 thus far. hope this helps… One last note, if you have webhooks you also need to implement them with the proper express.js calls and I am still to figure that out .

  • Marin Moldovanu

    I am working on migration parse.

    So I could migrate Parse DB to MongoDB using MongoLab.

    Also I could change parse-server-example;

    add cloud code(for mandrill-api and twilio) in main.js.(this works very well)

    deploy to Heroku.

    However, I have some issues here.

    On iOS development side, when the user logs in, app don’t progress any PFObject.

    if I am going to change user’s profile(string, boolean, image and so on), I get error message

    [Error]: Can’t upload a file that doesn’t exist locally. (Code: 151, Version: 1.12.0)

    If I am going to download the user’s photo, I get error message.

    [Error]: Can’t download a file that doesn’t exist on the server or locally. (Code: 151, Version: 1.12.0)

    Also I found a strange issue.

    After migration, I created a new account on my app.(without user’s photo)

    First, it seems it works very well

    But If I upload user’s photo, connection error occurs.

    What’s matter?

    I hope you can help me.


  • New files should upload and be stored as a native GridStore in MongoDB. I’d build a quick mockup that uploads new files to Mongo, without your app, to see what the issue is: is it Parse Server, your app’s code, or a failed data migration?

    Your old files still reside on Parse’s S3 servers. Follow the discussion on migration of legacy files on S3 here:

  • Rob Wright

    Here is the response from the support team at MongoLabs:
    “Hello, is it possible to set failIndexKeyTooLong=false on the shared cluster plan?

    Yes, you can set this parameter temporarily under the “Tools” tab for your deployment in the MongoLab management console. I should point out that by setting that option, it’s possible for data that exceed the maximum index key length (1024 bytes) to be excluded from indexes, which could lead to incomplete/incorrect query results.”

  • Marin Moldovanu

    Thanks a lot

    I’ve migrated successfully, and I am using the original code.
    Also I’ve done parse-server be parse guide.

    So I don’t know where this issue occurs.

    Then, to fix this issue, what can I do?

  • It sounds like your issue has nothing to do with the migration, but happens because of a failure in uploading and downloading files to Parse Server. I’d make a quick mockup app to see if the uploads work for ordinary files (ex. from the app’s bundle), so you can be sure that the problem is not server-side. Also, stay tuned in on the Issue # 8 on the parse-server GitHub repo, in case your error has something to do with mixing legacy S3 files and new Grid file uploads.

    In any case, your best bet to get help is in the GitHub Issue you already found:

  • Marin Moldovanu


    I can’t still fix this issue.

    However, I found a strange problem.

    When I create a new account, everything works very well.
    In other words, I can upload/download image.(current user’s profile photo)

    But I found new image’s URL and original image’s URL is different.

    new image’s URL:

    original image’s URL:


    I can see original image on Chrome. But I can’t see new image on Chrome. I got error message as following:
    “This XML file does not appear to have any style information associated with it. The document tree is shown below.

    Access Denied

    I can do everything with a new account on my mobile app.
    Please help me.

  • You’re seeing the XML in the browser because S3 files need to be authenticated before you can see them. Chrome doesn’t do that by itself. Did you set the fileKey configuration property on your app? You need to set it both in index.js and in the AppDelegate, and make sure it’s the same as the File Key in Parse Dashboard.

    I’m pretty sure your old app has S3 files and Grid storage mixed up.

  • Marin Moldovanu

    Thanks for your concern.

    I’ve already set fileKey in the index.js.
    And do you know how to set fileKey in the appDelegate? Please share it.

    Thanks again

  • See the code block below. Let me know when you’ve made significant progress, then we can discuss the issue further.

    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 || 'myMasterKey',
    fileKey: ''

  • Thanks Rob, this is a helpful addition!

  • tamer


    I have android app and i use this method to define parse Parse.initialize(this, “ApplicationKey”, “ClientKey);

    how to point my app to heroku server like your ios app ?

    Kindly advice


  • For Android, that would be similar to:

    Parse.initialize(new Parse.Configuration.Builder(myContext)


  • Saner


    Is it more difficult to use parse server in AWS Elastic Beanstalk? Parce announced that they working together with aws for this also, is it possible to add how to do it in AWS? And which one would be better heroku or AWS?

    Thank you very much

  • tamer


    but when i apply this solution this problem appear “cannot resolve symbol Configuration ”


  • You probably need to update the Parse SDK for Android.

  • tamer

    Thank you very much it work’s

  • AWS Elastic Beanstalk and Heroku are the same type of services, they’re Platform-as-a-Service providers that allow you to easily deploy your code in a “container” (a virtual server that does just one thing). You don’t have to worry about installing the latest NodeJS, or configuring databases, it’s just there, running in the container.

    It’s hard to say which is better, AWS Beanstalk or Heroku. It depends on the requirements of your project, so I recommend you compare what you want with what both products have to offer.

  • Hyder Abbas

    Dear Reinder,

    Thanks for you amazing tutorial. Done all the steps successfully that you’ve mentioned. Now when testing my app , I’m having issue when calling

    [PFUser logInWithUsernameInBackground:username password:password
    block:^(PFUser *user, NSError *error) {}];

    I’m getting error in result:

    NSError * domain: @”NSCocoaErrorDomain” – code: 3840
    “JSON text did not start with array or object and option to allow fragments not set.”

    What can be the most possible reason?

  • Thanks!

    That error code means your app couldn’t parse the JSON it got back from Parse, i.e. there’s an error in the JSON, it’s malformed, or it is missing data. I’m not sure what the exact cause is. Several issues on GitHub indicate that Parse Server behaves slightly different under certain circumstances, compared to the original Parse.

    Perhaps these issues help you:

  • Hyder Abbas

    I will look at the issues. Thanks Reinder! You’re helping a lot!

  • Tera Caijiawen

    Hi, Thank you for the tutorial.
    But the number of votes in mongoDB no update when i double click the images.
    In Xcode there log “2016-02-18 14:15:05.311 Paws[1014:9460] [Error]: unauthorized (Code: 0, Version: 1.12.0)” why?
    Thank you.

  • Yan Zhang

    You may see one “Finalize” button below this table. If you click it, it means that you will disconnect the original Parse server from your app and you will begin to only rely on the new Parse server which you have just set up. So make sure that you are prepared to disconnect before you finalize it. After you finalize, you should change your app code as in this tutorial and your app will be redirected to the new Parse server and use the data in your MongoDB.

  • Thanks for clarifying! Keep in mind that you should’ve connected your app to the new Parse Server before you finalize. As far as I know, requests to will use your MongoDB, so users that haven’t updated your app can still use it.

  • Yan Zhang

    Yes. It seems so. I changed back the lines in AppDelegate to the original and my app still works. It is good that Parse thinks thoroughly about the migration process and keeps the data in their server so that both old and new versions of apps can work at the same time.
    Thank you very much for your well-written tutorial! It saved me a lot of time from searching information on the Internet.
    Do you have any recommendation for the tier of Heroku and MongoDB? I have one app which has less than 30 requests/sec on Parse. I still don’t know if I should choose Hobby or Standard.

  • I think you can make an informed decision, for MongoLab, based on the size of your database and the amount of redundancy you need. For Heroku, start with a Hobby or Standard 1x now, and scale up when needed.

    You should monitor the load and work out what kind of setup you need for what kind of performance, i.e. “with 10 requests/sec and 100 concurrent users on average, and Standard 2x, my app performs OK / responsive”.

    Heroku is built for easy horizontal scaling, so generally you pick a vertical that’s capable of hosting your app (Standard / Performance, 1x / 2x) and then scale it out horizontally. If you can house 10.000 MAUs in 1 Standard 1x, and you get 10.000 more, you should be able to just start another Standard 1x dyno and be in the clear :-).

  • Yan Zhang

    Thanks a lot for your quick responses ! I will try a Hobby and scale it up if necessary. Hopefully it just doesn’t effect the app when scaling up.

  • Saner

    Hello Reinder, I finished migrating my parse app to mongolab and aws beanstalk, thank you for the tutorial it helped a lot. The only problem is that I can not retrieve images. How can I set the fileKey in the xcode project and server?

  • You should set the fileKey in index.js, and in your AppDelegate.

  • Hello Reinder, sorry for asking too many questions, how can I add the fileKey to app delegate, is there any example swift code for this?

    I tried: ParseMutableClientConfiguration.fileKey = “xxxxxxxxxxxx”;

    below the client key but it didn’t worked. I also added it to the AWS console as in the picture below:

  • You can never ask too much questions :-).

    In index.js:

    var api = new ParseServer({
    databaseURI: databaseUri || 'mongodb://localhost:27017/dev',
    appId: 'xxx',
    clientKey: 'xxx',
    masterKey: 'xxx',
    fileKey: 'xxx'

    If you’ve set the keys through environment variables, you of course don’t input the keys directly put instead reference the environment variables. Then, after, do this in Terminal:

    – Make sure you’re in the right project directory (~/heroku/parse-server-example in the article)
    – Type git add index.js
    – Type git commit -m "Changed Parse Server keys"
    – Make sure to deploy your changes to AWS. For Heroku, you’d use: git push heroku master. This deploys your changes and restarts the web process.

    In your app, change your AppDelegate config code lines to something similar to this:

    let config = ParseClientConfiguration(block: {
    (ParseMutableClientConfiguration) -> Void in
    ParseMutableClientConfiguration.applicationId = "...";
    ParseMutableClientConfiguration.clientKey = "...";
    ParseMutableClientConfiguration.server = "...";
    // file key, etc.

    Good luck!

  • Jack Strohanov


    Great article, thanks
    I have one issue that I can’t resolve
    [Error]: Response status code was unacceptable: 403 (Code: 1, Version: 1.12.0)
    as I saw in comments, I added fileKey to my index.js file, but there is a problem, that no fileKey I found for AppDelegateFile neither in ParseMutableClientConfiguration nor anywhere else, I’ve updated my Parse.framework file to 1.12.0 but there isn’t such property


  • Good point. You don’t have to set the fileKey in AppDelegate, only in the Parse Server’s index.js. When you access a legacy Parse file, Parse Server will direct the request to Parse’s S3 bucket. New files will be stored in MongoDB as GridFS. Keep in mind that Parse Server will use the old legacy S3 files if you don’t migrate them. Follow the issue below to stay in the loop; I think someone already made an S3 file adapter.

  • Tera Caijiawen

    Hi, great tutorial but i’m stuck when I launch Heroku open and get an application error. Then i type “heroku logs” in terminal. The following errors come out, i don’t know how to solve that, can you help me on that? thank you very much.

  • The error log says you didn’t provide a Server URL in index.js. Could you verify you’ve added the config values, and committed the changes to the repository? Also, check the syntax of the changes you made in index.js (commas, apostrophes, etc.).

  • max

    How do I connect to the new parse server within an application extension for ios in xcode?

  • Could you be more specific? You have to add Parse to your Xcode project / workspace (ex. with CocoaPods), then update the config values, install Parse Server (which is outside of Xcode), etcetera.

  • max

    Hello Reinder, thanks for the reply. After a few hours of investigation I have locked the problem down to reading and writing PFFiles. I have an application that reads and writes data in addition to an action application extension that allows files to be saved from email to my application container.

    All data (text field and picker data saves without issue after migrating to Heroku, my own Parae server and a MongoLab db. The only two things that appear not to work are authenticating a user (getting the current user objectid) via an application extension and saving and retrieving files don’t appear to work. If I simply revert back to using the old config values in both my main application and my app extension, everything works as expected.

    Is there a known problem with authentication via an application extension and with saving and retrieving PFFiles using the new open source Parse server and Mongo db hosted on Heroku?

  • I can’t help you Max, this is well beyond the scope of the code guide. Your best bet is isolating the issue, and filing a bug report on GitHub (for Parse Server / iOS SDK). You can always ask the authors for feedback, or open a question on StackOverflow. Good luck!

  • Peter

    Hey Reinder. Thanks for the straightforward tutorial. Could you just explain “It’s in a dependency, the library is called parse-server and you can find it’s code at:”. If the parse-server-example is dependent on the parse-server, then shouldn’t it also be pushed to the Heroku instance? Also how would I update my app instance with the new parse-server github updates. Thanks again.

  • Yes, it’s definitely a dependency. When you deploy your app to Heroku, during the “git push heroku master” step, the build script fetches and installs the dependency for you. You can see what packages parse-server-example relies on by looking at the package.json file. As far as I know, a new build triggered by a push will also update dependencies according to package.json. A scenario would be that you install parse-server-example locally, do the required code changes to stay compatible with the dependency, and then push and rebuild.

  • DASoftware

    Hello, excellent article… Quick question, got stuck on the last step. I do not use parse for iOS but for a .NET MVC application, i cannot find were to set up the heroku url to be used as the parse server. Thanks in advance.

  • Make sure you update to the latest version of the SDK you’re using. You could check in the docs if there’s a property or endpoint you can configure to use the right API URL.

  • nullptr

    Thank you very much for this tutorial. I have setup everything correctly, the only doubt is where to put cloud code, and background jobs.

  • You should put your cloud code in /cloud and invoke it from /cloud/main.js. There’s a high chance you’ll have to rewrite it, as most Parse-hosted services like sending emails won’t work with Parse.

    Read more about cloud code in the official guides from Parse:

  • nullptr

    Thank you for quick reply, i will definitely look into 🙂

  • Jeremy Kotai

    Fantastic tutorial! The only issue I’m having is that when I call the function -> user.signUpInBackgroundWithBlock{ (succeeded: Bool, error: NSError?) -> Void in } I get succeeded = false and error = nil. There is no information suggesting what to do or why it is failing without an error…immediately before migrating this sign up form was working. All calls are failing in this manner with no feedback. Anyone else have this issue?

  • Thanks :-).

    Hmm, odd error. Could you check with heroku logs what’s going on, or even check with an HTTP proxy what’s being sent to Parse? I’m having that exact line in one of my apps and it’s working fine with Parse Server.

  • Sam1_R

    What Server URL should be used? The default is to a local host, what should this be?

  • Mike

    Very clear! but I got also an err when run Heroku. Does this logs speaks to you? big thanks for your help Reinder

  • Not entirely sure what happens here, but check the syntax of the ParseServer configuration block. Make sure to type the commas, colons, apostrophes, etc. My guess is the line before serverURL doesn’t have an ending comma — but I’ve been wrong before 😉

  • Mike

    Thanks for replying. I’ve checked but see nothing about coma missing. Look code below.

  • Mike

    I have pushed change and now it run with web message –>{“error”:”unauthorized”}

  • Awesome. That means it works ;-). On the web, if you don’t include authorization headers (with the master key and App ID), you’ll see this error. Try again in your app and make sure you set the right App ID and Master Key. If you specifically set the clientKey, you need to include that as well. In any case, your Parse Server is running, you can essentially continue with chapter 4 of the guide.

  • Mike

    Thanks Reinder. I will try to go ahead

  • Mike

    After setup appID, clientKey and serveur with custom data. I do not have data anymore that display. weird..

  • Are you migrating the Paws app? In that case, make sure you actually have migrated the data into Parse Server (with the Parse Migration Tool). If you didn’t have a Parse account before the shutdown, follow the instructions from chapter “Importing Data with mLab” to upload the Paws data right into MongoDB (without migrating first).

  • Mike

    I did it already and it look good. The link i have is the same than the DATABASE_URI in Heroku & MLab. I will continue to investigate

  • waploaj/duurhla

    this tutorial is the best tutorial but am kind of stuck in middle
    when i edit this line in Xcode”

    let config = ParseClientConfiguration (block: {

    ” i get an error unresolved object Y? can you help me

  • waploaj/duurhla

    screen shot

  • Make sure you update your Parse for iOS SDK to the latest version. Also, append /parse to your serverURL (not just “server”).

  • waploaj/duurhla

    thank u man can you give me the link pls

  • viki donald

    Having the application Error. please help to resolve this

  • viki donald

    Having the application Error. please help to resolve this.

  • You best ask help for this in the Parse Server GitHub repository or on StackOverflow. It looks like an application error, not sure what’s going on.

  • viki donald

    these are my test app credentials. Everything looks fine but when i open heroku it shows application error and after this I run heroku logs which shows the above logs.

  • IMPORTANT: Don’t share your app’s credentials publicly! You should keep your passwords, master key etc. secret and safe at all costs. I’ve deleted your original comment. It’s a good idea to change your keys and passwords now. Quick tip: don’t choose “admin” as a password… Instead, generate a random password with

    Like I mentioned, you’re facing an application error, not an error in your configuration file. It appears LiveQuery breaks on your version of Parse Server. You should check out this issue on the GitHub repo, it mentions the exact same error:

  • viki donald

    Ok, Here I have attached my test app credentials it looks fine. Parse Server has fixed the line 335 issue but still I am getting multiple npm errors.
    Do we need to install npm into parse-server-example

  • Listen up! This is the second time today you’re sharing your MongoDB username and password publicly in the comments. Anyone on this page can log into your database, change your data, remove it, etc. Same goes for your Parse Server master key. It’s even written in the screenshot: “Keep it secret!”

    I removed your previous comment to help you, but you just added it back again.

    As for the error you’re seeing, like I said, I can’t solve it for you, but it’s most likely a bug in Parse Server. If you think the GitHub repo now has a fix, you should update your Parse Server app with add, commit, push.

  • viki donald

    Ok Reinder Thanks for your help. You are great the issue is of parse server and they have now resolved it.

  • Giovanny piñeros

    Hi, first of all thank you for the complete guide. Im using parse server and heroic, but I’m trying to build this iOS app with Facebook log in, i do not know how to set the Facebook app id to the parse server app, before this was made in the parse dashboard, now i do not now how. can you help me, please. Im only a mobile developer, and have no expertise yet on backend services.

  • yoshiboarder

    Hi Thank you for great guide.

    I’m trying to set parse server on my machine…

    $ npm install -g parse-server mongodb-runner
    $ mongodb-runner start
    $ parse-server –appId APPLICATION_ID –masterKey MASTER_KEY –databaseURI mongoldb:(my mLab url).

    I also uploaded cat db to my mongoldb…

    after that I’m trying run your example code.. AND I got these logs….

    Could you advise me?

    Thank you

    2016-03-26 14:11:28.353 Paws[32449:5857875] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app’s Info.plist file.

    2016-03-26 14:11:28.355 Paws[32449:5857863] [Error]: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection. (Code: 100, Version: 1.13.0)

    2016-03-26 14:11:28.355 Paws[32449:5857863] [Error]: Network connection failed. Making attempt 1 after sleeping for 1.965438 seconds.

    2016-03-26 14:11:30.322 Paws[32449:5857856] [Error]: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection. (Code: 100, Version: 1.13.0)

    2016-03-26 14:11:30.323 Paws[32449:5857856] [Error]: Network connection failed. Making attempt 2 after sleeping for 3.930877 seconds.

  • AFAIK, Facebook Login works just like before. In your Parse Server configuration (in index.js) you need to set the facebookAppIds key. It’s value is an array of Facebook App IDs. You best check out the docs and migration guide for more info:

  • iOS 9 blocks cleartext HTTP requests by default. You can change a setting in your .plist file to fix the error, read here how:

  • yoshiboarder

    Thank you for reply! I solved this problem 🙂

  • RS

    Hi Reinder, thanks for a great tutorial! I got it working through the Paws, but am having trouble on my own app. It has a few more classes, but I am unsure why it’s not working on the iOS side(I know the heroku is working (verified through the logs) and mLabs has all the tables).

    Is there anything in addition I should be implementing for it to work on my own app?

  • Thanks, you’re welcome! It’s hard to say what’s going on with your app without more information. Could you elaborate on what exactly isn’t working? Cloud Code, Push and several other integrations don’t work out of the box.

  • RS

    Thanks for the fast reply. It’s a simple app so it isn’t using any integrations except for Push, but I can’t get a table queried and filled with data like the Paws app.

    I am using parse’s queryfortable function and then filling a tableview with text from a data class similar to the Paws app but when I load the table there are no results being returned and the table is empty.

  • Alright, try this:

    – Check if the data is actually in the MongoDB database. You can also use (admin panel). Make sure to double check your client key, app ID, etc. to be sure you’re talking to the right database.
    – Enable client-side logging and check the data that’s being sent, see: Use a proxy like Charles if possible, so you can see the data being exchanged. You can also use the method objectsDidLoad: on PFQueryTableViewController, as long as the data is getting to your app.
    – Double check the query in queryForTable:. If you’re using fancy stuff like relations, check on GitHub for Parse Server whether there’s an issue with that type of query.
    – If you’re sure your data is getting to your app, it could be not strictly related to Parse. Are you refreshing your table views? Are you looking at the right code? Is what you think should be executed, executed?

  • Naveen Rana

    Hey Reinder, I Want to confirm I create a website using parse in PHP when i migrate Parse Server to mlab. then i need to create website again or everything is working .Please confirm asap

    If anything changes then can you provide help like as tutorial. etc

  • Erika Hudiono

    Hi, I just got to the “heroku open” command, and the web page only opens up to a “Application Error:An error occurred in the application and your page could not be served. Please try again in a few moments.”, specifically 503: Service Unavailable in the console. What is happening?

  • Erika Hudiono

    I am still getting the “Application Error” whenever I get to “heroku open”. What is causing this? I followed it step by step

  • OK, got it. Did you do git push heroku master, and did you see any errors in the output? Also, check heroku logs for any leads into what might cause the application error.

  • Nobles Antwi

    Thank you for this guide. One problem, when i input in terminal “git add index.js” I get fatal: pathspec ‘index.js’ did not match any files. thanks

  • Thanks! Make sure you’re in the right directory, the one that has the .git directory in it (~/heroku/parse-server-example in the guide). You can always check the changes you made with “git status”.

  • Nobles Antwi

    It worked. Thank you very much! Made my morning

  • Awesome! Glad I could help.

  • Nobles Antwi

    All done. Got it up. Thanks a lot man. Great guide and help

  • Great! Well done 🙂

  • Fahid Javed

    You have done a great work.

    I followed your tutorial and successfully completed all steps but the thing is when ever I update the value of anything through my app it update value on both parse and mlab data base. How should I know that heroku is working fine with my app? or still parse is working.

  • Thanks! Glad you like it, Fahid.

    Did you finalize your migration with the old Parse? When the migration is final, Parse will route requests to your new mLab database so that current installations — the ones that still connect to Parse — will keep running. New installations of your app will use your own Parse Server on Heroku, and connect to the mLab database. In this scenario, then, both the old Parse and your own new Parse Server will connect and write to the same mLab database.

    You can verify that your new Parse Server is functioning OK by making sure the app connects to Parse Server. If that works, your Parse Server instance is set up correctly and you won’t need the old Parse any more (except for current users, if you’re migrating a live app). You can read how to configure your app to connect to Parse Server at the very end of the guide on this page, at “4. Configuring The “Paws” App”.

    Good luck!

  • Fahid Javed

    I have finalised the parse migration. You can see attached image.
    Attached my index.js.
    Attached my Parse Init.
    Whenever any change occurs in database it updates both databases parse and mlab. I am still confused.
    My heroku app is also showing zzzz. I think its not active even I am continuously using my app on my phone.
    Any Suggestions

  • Don’t share your app’s master key publicly! Your screenshot clearly says “Keep it secret!”. Any idiot can remove pretty much everything in your app right now with the info on screen: your Heroku URL and app master key. I’ll remove the image.

    I’m not sure what’s going on, and provided you’re migrating your own app and I’m not a one-on-one consultant I’m afraid I cannot help you much further. Your best bet would be to ask help on StackOverflow. In any case, make sure you’re running the right code on your Android phone. It’s OK that the old Parse connects to your mLab database, like I explained, it’s supposed to do that.

  • Zahra

    thank you for this article. but could you please explain the last step for android apps?

On The Blog