Configuring a Parse Server - TechGeekD/android_guides GitHub Wiki
Parse provides a cloud-based backend service to build data-driven mobile apps quickly. Facebook, which acquired the company more than 3 years ago, announced that the service would be shutting down on January 28, 2017. An open source version enables developers to continue using their apps was published, along with a migration guide.
While there are many alternate options to Parse, most of them lack either the functionality, documentation, or sample code to enable quick prototyping. For this reason, the open source Parse version is a good option to use with minimal deployment/configuration needed.
You can review this Wiki to understand the current development progress of this app. There are a few notable differences in the open source version:
-
Authentication: By default, only an application ID is needed to authenticate with open source Parse. The base configuration that comes with the one-click deploy options does not require authenticating with any other types of keys. Therefore, specifying client keys on Android or iOS is not needed.
-
Push notifications: Because of the implicit security issues with allowing push notifications to be sent through Android or iOS directly to other devices, this feature is disabled. Normally in Parse.com you can toggle an option to override this security restriction. For open source Parse, you must implement pre-defined code written in JavaScript that can be called by the clients to execute, otherwise known as Parse Cloud.
-
Single app aware: The current version only supports single app instances. There is ongoing work to make this version multi-app aware. However, if you intend to run many different apps with different datastores, you currently would need to instantiate separate instances.
-
File upload limitations: The backend for open source is backed by MongoDB, and the default storage layer relies on Mongo's GridFS layer. The current limit is set for 20 MB but if you depend on storing large files, you should really configure the server to use Amazon's Simple Storage Service (S3).
Many of the options need to be configured by tweaking your own configuration. You may wish to fork the code that helps instantiate a Parse server and change them based on your own needs. The guide below includes instructions on how to add push notifications and storing files with Parse.
The steps described this guide walk through most of the process of setting an open source version with Parse. There are obviously many other hosting options, but the one-click deploys made available with Heroku or Amazon AWS as discussed in this guide are the simplest. In both cases, you are likely to need a credit card attached to your account to activate.
Use Heroku if you have little or no experience with setting up web sites. Heroku allows you to manage changes to deploy easily by specifying a GitHub repository to use. In addition, it comes with a UI data viewer from MongoLabs.
-
Sign Up / Sign In at Heroku
-
Click on the button below to create a Parse App
-
Make sure to enter an App Name. Scroll to the bottom of the page.
-
Make sure to change the config values.
- Leave
PARSE_MOUNT
to be/parse
. It does not need to be changed. - Set
APP_ID
for the app identifier. If you do not set one, the default is set asmyAppId
. You will need this info for the Client SDK setup. - Set
MASTER_KEY
to be the master key used to read/write all data. Note: in hosted Parse, client keys are not used by default. - Set
SERVER_URL
to behttp://yourappname.herokuapp.com/parse
. Assuming you have leftPARSE_MOUNT
to be /parse, this will enable the use of Parse Cloud to work correctly. - If you intend to use Parse's Facebook authentication, set
FACEBOOK_APP_ID
to be the FB application ID. - If you intend to setup push notifications, there are additional environment variables such as
GCM_SENDER_KEY
andGCM_API_KEY
that will need to be configured. See this section for the required steps.
- Leave
-
Deploy the Heroku app. The app should be hosted at
https://<app name>.herokuapp.com
.
If you ever need to change these values later, you can go to (https://dashboard.heroku.com/apps/<app name>/settings
). Check out this guide for a more detailed set of steps for deploying Parse to Heroku.
Now, we can test our deployment to verify that the Parse deployment is working as expected!
Note: You need to setup only Heroku above OR Amazon below but not both in order to use Parse.
Amazon AWS provides more advanced functionality, such as a load balancer, easy-to-upgrade instances, and auto-scaling groups. Use only if you are more comfortable with managing servers. You do not get a UI data viewer out of the box.
-
You can create a new Parse instance by clicking on the button:
-
Create an application name and click on
Review and Launch
. Clicking onNext
will take you the more advanced settings. -
The final step is to review your changes. Click
Launch
when ready. -
The machine configuration should begin to start. Look for the
Software Configuration
panel to appear:<img src="http://imgur.com/YATjJlc.png"/>
-
Configure the environment variable settings.
- Set
APP_ID
for the app identifier. If you do not set one, the default is set asmyAppId
. You will need this info for the Client SDK setup. - Set
MASTER_KEY
to be the master key used to read all data. - Leave
PARSE_MOUNT
to be/parse
. It does not need to be changed. - Set
SERVER_URL
to behttp://yourappname.herokuapp.com/parse
. Assuming you have leftPARSE_MOUNT
to be /parse, this will enable the use of Parse Cloud to work correctly. - If you intend to use Facebook authentication, set
FACEBOOK_APP_ID
to be the FB application ID.
- Set
-
Your machine should take a few minutes to spin up. Once it's ready, you should be able to click on the URL provided:
<img src="http://imgur.com/OjyvPdc.png"/>
Other tips:
-
If you need to update the source code, you need to go the download the updated
.zip
file and upload to the main dashboard here:<img src="http://imgur.com/8XBkbnK.png"/>
-
If you need to get back to the console after the instance has been created, you can click here.
-
You mean need to get direct SSH access to this box to view the MongoDB data. See this article for more information.
Now, we can test our deployment to verify that the Parse deployment is working as expected!
After deployment, try to connect to the site. You should see I dream of being a web site.
if the site loaded correctly. If you try to connect to the /parse
endpoint, you should see {error: "unauthorized"}
. If both tests pass, the basic configuration is successful.
Next, make sure you can create Parse objects. You do not need a client Key to write new data:
curl -X POST -H "X-Parse-Application-Id: myAppId" -H "X-Parse-Master-Key: abc" \
-H "Content-Type: application/json" \
-d '{"score":1337,"playerName":"Sean Plott","cheatMode":false}' \
https://yourappname.herokuapp.com/parse/classes/GameScore
Be sure to replace the values for myAppId
and the server URL. If you see Cannot POST
error then be sure both the X-Parse-Application-Id
and the URL are correct for your application. To read data back, you will need to specify your master key as well:
curl -X GET -H "X-Parse-Application-Id: myAppId" -H "X-Parse-Master-Key: abc" \ https://yourappname.herokuapp.com/parse/classes/GameScore
Be sure to replace the values for myAppId
and the server URL. If these commands work as expected, then your Parse instance is now setup and ready to be used!
The hosted Parse instance deployed uses MongoLab to store all of your data. MongoLab is a hosted version of MongoDB which is a document-store which uses JSON to store your data.
If you are using Heroku, you can verify whether the objects were created by clicking on the MongoDB instance in the Heroku panel:
You can also setup Robomongo to connect to your remote mongo database hosted on Heroku to get a better data browser and dashboard for your app.
Using that cross-platform app to easily access and modify the data for your Parse MongoDB data.
Make sure you have the latest Parse-Android SDK in your app/build.gradle
file. It should be at least 1.13.0
:
dependencies {
compile 'com.parse:parse-android:1.13.0'
compile 'com.parse:parseinterceptors:0.0.2' // for logging API calls to LogCat
compile 'com.parse.bolts:bolts-android:1.+'
}
If you are migrating from a previous Parse configuration, make sure to delete the CLIENT_KEY
reference in your AndroidManifest.xml
file. You can in fact delete both lines since we will be using a custom config builder in the next step.
<!--- these lines should be deleted in lieu of our custom Parse builder -->
<meta-data
android:name="com.parse.APPLICATION_ID"
android:value="myAppId" />
<meta-data
android:name="com.parse.CLIENT_KEY"
android:value="clientKey" />
<!--- end of delete --->
Modify your Parse.initialize()
command to point to this newly created server. You must be on the latest Parse Android SDK to have these options.
public class ChatApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// set applicationId, and server server based on the values in the Heroku settings.
// clientKey is not needed unless explicitly configured
// any network interceptors must be added with the Configuration Builder given this syntax
Parse.initialize(new Parse.Configuration.Builder(this)
.applicationId("myAppId") // should correspond to APP_ID env variable
.clientKey(null) // set explicitly unless clientKey is explicitly configured on Parse server
.addNetworkInterceptor(new ParseLogInterceptor())
.server("https://parse-testing-port.herokuapp.com/parse/").build());
}
}
Note: make sure to use the extra trailing /
when using the .server()
call. There appears to be a bug in the Android SDK that strips the URL without this trailing slash.
The /parse/
path needs to match the PARSE_MOUNT
environment variable, which is set to this value by default.
-
If you see
Application Error
orAn error occurred in the application and your page could not be served. Please try again in a few moments.
, double-check that you set aMASTER_KEY
in the environment settings for that app. -
If you are using Heroku, download the Heroku Toolbelt app here to help view system logs.
First, you must login with your Heroku login and password:
heroku login
You can then view the system logs by specifying the app name:
heroku logs --app <app name>
The logs should show the response from any types of network requests made to the site. Check the
status
code.2016-02-07T08:28:14.292475+00:00 heroku[router]: at=info method=POST path="/parse/classes/Message" host=parse-testing-port.herokuapp.com request_id=804c2533-ac56-4107-ad05-962d287537e9 fwd="101.12.34.12" dyno=web.1 connect=1ms service=2ms status=404 bytes=179
-
If you are seeing
Master key is invalid, you should only use master key to send push
, chances are you are trying to send Push notifications without enable client push. On Parse.com you can simply enable a toggle switch but for hosted parse there is an outstanding issue that must be resolved to start supporting it. -
You can also use Facebook's Stetho interceptor to watch network logs with Chrome:
dependencies { compile 'com.facebook.stetho:stetho:1.3.0' }
And add this network interceptor as well:
Stetho.initializeWithDefaults(this); // init Stetho before Parse Parse.initialize(new Parse.Configuration.Builder(this) .addNetworkInterceptor(new ParseStethoInterceptor())
-
If you wish to troubleshoot your Parse JavaScript code is to run the Parse server locally (see instructions). You should also install node-inspector for Node.js, which allows you to use Chrome or Safari to step through the code yourself:
npm install node-inspector node --debug index.js node_modules/.bin/node-inspector
Open up http://127.0.0.1:8080/?port=5858 locally. You can use the Chrome debugging tools to set breakpoints in the JavaScript code.
Point your Android client to this server::
Parse.initialize(new Parse.Configuration.Builder(this) .applicationId("myAppId") .server("http://192.168.3.116:1337/parse/") // lookup your IP address of your machine
Note: Support for push notifications is now available with the open source Parse server. However, unlike Parse's own service, you cannot implement this type of code on the actual client:
// Note: This does NOT work with Parse Server at this time
ParsePush push = new ParsePush();
push.setChannel("mychannel");
push.setMessage("this is my message");
push.sendInBackground();
You will likely see this error in the API response:
{
"code": 115,
"error": "Master key is invalid, you should only use master key to send push"
}
Instead, you need to write your own server-side Parse code and have the client invoke it. Fortunately, the process is fairly straightforward:
-
Fork this repo. This repo is similar to the package that you used for your one-click deploy. This repo has some additional environment variables configurations added that help facilitate sending push notifications (i.e. see
GCM_SENDER_ID
, andGCM_API_KEY
in index.js) -
Make sure to confirm the
SERVER_URL
environment variable is set to the URL and Parse mount location (i.e.http://yourappname.herokuapp.com/parse
). -
Verify that
cloud/main.js
is the default value ofCLOUD_CODE_MAIN
environment variable. -
Modify cloud/main.js yourself to add custom code to send Push notifications. See these examples for other ways of sending too.
- If you use Parse's default ParsePushBroadcastReceiver, using either
alert
ortitle
as a key/value pair will trigger a notification message. See this section of the Parse documentation. - You can also create your own custom receiver as shown in this example.
- If you use Parse's default ParsePushBroadcastReceiver, using either
-
Redeploy the code. If you are using Heroku, you need to connect your own forked repository and redeploy.
-
Enable Google Cloud Messaging for your Android client (see instructions below).
-
Assuming the function is named
pushChannelTest
, modify your Android code to invoke this function by using thecallFunctionInBackground()
call. Any parameters should be passed as aHashMap
:HashMap<String, String> test = new HashMap<>(); test.put("channel", "testing"); ParseCloud.callFunctionInBackground("pushChannelTest", test);
-
Make sure to register the GCM token to the server:
Parse.initialize(...); // Need to register GCM token ParseInstallation.getCurrentInstallation().saveInBackground();
- If you are using Facebook's Stetho library with your Android client, you can see the LogCat statements and verify that GCM tokens are being registered by API calls to the
/parse/classes/_Installation
endpoint:
: Url : http://192.168.3.116:1337/parse/classes/_Installation
You should be able to se the deviceToken
, installationId
, and appName
registered:
03-02 03:17:27.859 9362-9596/com.test I/ParseLogInterceptor:
Body : {
"pushType": "gcm",
"localeIdentifier": "en-US",
"deviceToken": XXX,
"appVersion": "1.0",
"deviceType": "android",
"appIdentifier": "com.test",
"installationId": "XXXX",
"parseVersion": "1.13.0",
"appName": "PushNotificationDemo",
"timeZone": "America\/New_York"
}
-
In your Parse server (
index.js
), make sure you do not have any of optional keys set (i.e.clientKey
,javascriptKey
,restAPIKey
,dotNetKey
). If any of them are set, it's very likely you will see a 403 status code on the API response for any Android clients. The reason is that the open source Parse version will fail if any required keys are needed. -
If GCM is fully setup, your app if properly configured should register itself with your Parse server. Check your
_Installation
table to verify that the entries were being saved. Clear your app cache or uninstall the app if an entry in the_Installation
table hasn't been added. -
Inside your
AndroidManifest.xml
definition, make sure yourgcm_sender_id
is prefixed withid:
(i.e.id:123456
). Parse needs to begin with anid:
to work correctly. -
Make sure that your SERVER_URL is set on the client side with a trailing '/'.
-
You can use this curl command with your application key and master key to send a push to all Android devices:
curl -X POST -H "X-Parse-Application-Id: myAppId" -H "X-Parse-Master-Key: myMasterKey" \
-H "Content-Type: application/json" \
-d '{"where": {"deviceType": "android"}, "data": {"action": "com.example.UPDATE_STATUS", "newsItem": "Man bites dog", "name": "Vaughn", "alert": "Ricky Vaughn was injured during the game last night!"}}' \
https://parse-testing-port.herokuapp.com/parse/push/
- Use
heroku logs --app <app_name>
to see what is happening on the server side:
2016-03-03T09:26:50.032609+00:00 app[web.1]: #### PUSH OK
If you see Can not find sender for push type android
, it means you forgot to set the environment variables GCM_SENDER_ID
and GCM_API_KEY
.
-
Make sure you have not included
com.google.android.gms:play-services-gcm:8.4.0
in your Gradle configuration. Parse's Android SDK library already includes code to deal with the GCM registration. -
Verify that you have all the permissions for GCM setup in your
AndroidManifest.xml
file and that you have the correct receivers configured.
-
Make sure you have Google Play installed on the emulator or device, since push notifications via Google Cloud Messaging (GCM) will only work for devices and emulators that have Google Play installed.
-
Obtain a Sender ID and API Key.
- Follow only step 1 of this guide to obtain the Sender ID (equivalent to the Project Number) and API Key. You do not need to follow the other steps because Parse provides much of code to handle GCM registration for you.
-
Set
GCM_SENDER_KEY
andGCM_API_KEY
environment variables to correspond to the Sender ID and API Key in the previous step. Note: this step only works if you have setup your Parse server to enable push support. See the CodePath fork as an example about how to initialize the Parse server. -
Add a
meta-data
with the Sender ID in your AndroidManifest.xml. Make sure theid:
is used as the prefix (Android treats any metadata value that has a string of digits as an integer so Parse prefixes this value). If you forget this step, Parse will register with its own Sender ID but you will seeSenderID mismatch
errors when trying to issue push notifications.<meta-data android:name="com.parse.push.gcm_sender_id" android:value="id:SENDER_ID_HERE"/>
-
Add the necessary permissions (i.e.
com.google.android.c2dm.permission.WAKE_LOCK
,com.google.android.c2dm.permission.RECEIVE
,com.yourpackagename.permission.C2D_MESSAGE
, etc.) Make sure to change any instances ofcom.codepath.parseportpush
to your application package name. If you forget any of these permissions, it is likely the GCM registration will not succeed.<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <!-- IMPORTANT: Change "com.codepath.parseportpush.permission.C2D_MESSAGE" in the lines below to match your app's package name + ".permission.C2D_MESSAGE". --> <permission android:protectionLevel="signature" android:name="com.codepath.parseportpush.permission.C2D_MESSAGE" /> <uses-permission android:name="com.codepath.parseportpush.permission.C2D_MESSAGE" /> <service android:name="com.parse.PushService" /> <receiver android:name="com.parse.ParsePushBroadcastReceiver" android:exported="false"> <intent-filter> <action android:name="com.parse.push.intent.RECEIVE" /> <action android:name="com.parse.push.intent.DELETE" /> <action android:name="com.parse.push.intent.OPEN" /> </intent-filter> </receiver> <receiver android:name="com.parse.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND"> <intent-filter> <action android:name="com.google.android.c2dm.intent.RECEIVE" /> <action android:name="com.google.android.c2dm.intent.REGISTRATION" /> <!-- IMPORTANT: Change "com.codepath.parseportpush" to match your app's package name. --> <category android:name="com.codepath.parseportpush" /> </intent-filter> </receiver>
You can continue to save large files to your Parse backend using ParseFile
without any major changes:
byte[] data = "Working at Parse is great!".getBytes();
ParseFile file = new ParseFile("resume.txt", data);
file.saveInBackground();
By default, the open source version of Parse relies on the MongoDB GridStore adapter to store large files. There is an alternate option to leverage Amazon's Simple Storage Service (S3) but still should be considered experimental.
If you wish to store the files in an Amazon S3 bucket, you will need to make sure to setup your Parse server to use the S3 adapter instead of the default GridStore adapter. See this Wiki for how to configure your setup. The steps basically include:
- Modify the Parse server to use the S3 adapter. See these changes as an example.
- Create an Amazon S3 bucket.
- Create an Amazon user with access to this S3 bucket.
- Generate an authorized key/secret pair to write to this bucket.
- Set the environment variables:
- Set
S3_ENABLE
to be 1. - Set
AWS_BUCKET_NAME
to be the AWS bucket name. - Set
AWS_ACCESS_KEY
andAWS_SECRET_ACCESS_KEY
to be the user that has access to read/write to this S3 bucket.
- Set
When testing, try to write a file and use the Amazon S3 console to see if the files were created in the right place.