Parse is a suite of cloud based APIs, services and libraries that focus on letting developers build out rich applications and less time dealing with the overhead of setting up and managing databases, push notifications, social sign on, analytics, and even hosting and servers.
In this series I'll overview the options around developing an application that leverages Parse, including using Cloud Code to deploy your Node.js app to Parse's own hosting service.
4. “Parse's vision is to let developers
build any mobile app without
dealing with servers.”
6. a suite of tools to replace or support
your app’s backend
Parse Data
Parse Push
Parse Social Parse Analytics Parse Hosting
Cloud Code
Backend-as-a-Service (BaaS)
12. +
Generate an Express App
yo express
Install Parse module
npm install parse
Run Server
grunt
13. Alternative Node-Parse Modules
“IMPORTANT NOTE: This api is not currently maintained. If
I were starting a parse project today using node.js, I would
probably start out with https://github.com/shiki/kaiseki”
npm install node-parse-api
A Parse.com REST API client for Node.js
npm install kaiseki
https://parse.com/docs/rest
14. Quick-Start
https://parse.com/apps/quickstart#js/native/blank
Import and Initialize Parse Module
var Parse = require('parse').Parse;
Parse.initialize(“Application ID", “JavaScript Key");
Save a “TestObject”
var TestObject = Parse.Object.extend("TestObject");
var testObject = new TestObject();
testObject.save({foo: "bar"}, {
success: function(object) {
alert("yay! it worked");
}
});
16. Parse Data
Store your app’s data in the cloud. No servers necessary.
https://parse.com/products/data
17. Parse Data Objects
Data is schema-less
Automatic objectId, createAt and modifiedAt fields
Objects can be extended from other objects (classes)
Objects can be relational
{
objectId : "xWMyZ4YEGZ",
score: 1337,
playerName : "Sean Plott",
cheatMode : false,
createdAt : "2011-06-10T18:33:42Z",
updatedAt : "2011-06-10T18:33:42Z"
}
18. Object API
https://www.parse.com/docs/js_guide#objects
var Class = Parse.Object.extend("ClassName");
var item = new Class();
item.method({params},{callbacks})
item.save({"field" : "value"}, {
success : function(obj) {
// Execute any logic that should take place after the object is saved.
},
error : function(obj,error) {
// Execute any logic that should take place if the save fails.
// error is a Parse.Error with an error code and description.
}
})
19. Object Methods
•
save(params,callback) - save params to your object
•
fetch(callbacks) - refresh an object
•
set(field,value)/get(field) - stage params for saving to object
•
increment/decrement(field,value) - ++ and - -
•
destroy(callbacks) - delete an object
•
unset(field) - delete a field
•
add, addUnique, remove - array specific methods
http://www.parse.com/docs/js/symbols/Parse.Object.html
20. Query API
Retrieve many objects at once, put conditions on the objects
you wish to retrieve, and more
var GameScore = Parse.Object.extend("GameScore");
var query = new Parse.Query(GameScore);
query.equalTo("playerEmail", “blazor777@blah.com");
query.find({
success: function(object) {
// Successfully retrieved the object.
},
error: function(error) {
// Handle error
}
});
https://www.parse.com/docs/js_guide#queries
21. Query Methods
•
get(objectId,callbacks) - get one object by ID
•
find(callbacks) - runs query and returns results
•
equalTo, notEqualTo, etc - stage filters for query results
•
limit(num)/skip(num) - stage range for query results
•
ascending/descending - stage order for query results
•
first(callbacks) - like find, but just the first match
•
count(callbacks) - if you just want to know total of results
http://www.parse.com/docs/js/symbols/Parse.Query.html
22. Object Pointers
One-to-one and one-to-many relationships are modeled by
saving a Parse.Object as a value in the other object (pointer).
var
var
var
var
Portfolio = Parse.Object.extend("Portfolio");
item = new Portfolio();
Comment = Parse.Object.extend("Comment");
post = new Comment();
post.save({'message' : "this is great!"},{
success : function() {
item.set("comments",[post]);
item.save();
}
});
Saving an Object pointer
{
],
}
"comments": [
{
"__type": "Pointer",
"className": "Comment",
"objectId": "YrLhRXbnfc"
}
"objectId": "Z8CarHlfu2",
"createdAt": "2013-11-05T20:06:59.130Z",
"updatedAt": "2013-11-05T20:06:59.130Z"
Pointer Data without being fetched
By default, when fetching an object, related Parse.Objects are not fetched. These
objects' values cannot be retrieved until they have been fetched
23. Object Relations
Many-to-many relationships are modeled using Parse.Relation.
var
var
var
var
Portfolio = Parse.Object.extend("Portfolio");
item = new Portfolio();
Comment = Parse.Object.extend("Comment");
post = new Comment();
post.save({'message' : "this is great!"},{
success : function() {
var relation = item.relation("comments");
relation.add(post);
item.save();
}
});
Saving an Object relation
var relation = item.relation(“comments");
var query = relation.query();
query.equalTo("author", “Sam");
query.limit(10);
"
"
query().find({
success: function(list) {
// list of all relation results
}
});
Retrieve relation data using Query API
By default, the list of objects in this relation are not downloaded. You can get a list
of the posts that a user likes by using the Parse.Query returned by query.
25. Lots of other Data goodness
Every asynchronous method in the Parse JavaScript SDK
returns a Promise
Object instance and class methods
A Parse.Collection is an ordered set of Parse.Objects. It is
compatible with Backbone.Collection, and has all the same
functionality.
Parse.File lets you store application files in the cloud
27. Enabling Push Notifications
To send notifications from the JavaScript SDK outside of Cloud
Code or any of the other client SDKs, you will need to set Client
Push Enabled in the Push Notifications settings of your Parse app.
Flip this to get started
28. Parse Channels
Allows you to use a publisher-subscriber model for sending pushes.
Parse.Push.send({
channels: [ "Giants", "Mets" ],
data: {
alert: "The Giants won against the Mets 2-3."
}
}, {
success: function() {
// Push was successful
},
error: function(error) {
// Handle error
}
});
The channels subscribed to by a given Installation are stored in the
channels field of the Installation object.
Installation Object modification not available in
JavaScript SDK
29. Push Options
•
alert- your notification’s message
•
badge (iOS) - # of pending notifications on your app
•
sound (iOS) - play a sound file in your application
bundle
•
content-available (iOS) - for Newsstand apps
•
action (android) - Intent to be executed when received
•
title (android)- displayed in notification tray
30. Advanced Targeting
While channels are great for many applications, sometimes you need
more precision when targeting the recipients of your pushes.
var query = new Parse.Query(Parse.Installation);
query.equalTo('channels', 'Pirates'); // Set our channel
query.equalTo('scores', true);
Parse.Push.send({
where: query,
data: {
alert: "Pirates scored against the Cardinals! It's now 3-2."
}
}, {
success: function() {
// Push was successful
},
error: function(error) {
// Handle error
}
});
Data stored in Installation Object can be used with Query API
31. Receiving Pushes…
The JavaScript SDK does not currently support
subscribing iOS and Android devices for pushes
The JavaScript SDK does not currently support
receiving pushes.
34. Parse User
Parse.User is a subclass of Parse.Object, and has all the same features
var user = new Parse.User();
user.set("username", "Nick");
user.set("password", "voltan123");
user.set("email", "nick@hotmail.com");
// other fields can be set just like with Parse.Object
user.set("phone", "XXX-XX-XXXX");
user.signUp(null, {
success: function(user) {
// Hooray! Let them use the app now.
},
error: function(user, error) {
// Show the error message somewhere and let the user try again.
}
});
•
username - required, makes sure username is unique
•
password - required, stores as hidden hash
•
email - optional, makes sure email is unique
35. User API
•
signUp(params,callback) - create new User
•
logIn(user,pass,callbacks) - authenticate User
•
logOut() - sign out User
•
save(params,callbacks) - update User fields
•
User.current()- get current User from localStorage
•
User.requestPasswordReset(email, options)
http://parse.com/docs/js/symbols/Parse.User.html
36. Setup for Facebook Integration
1.
Setup a Facebook App
2.
Add Facebook JS SDK to your app
3.
Add FB App ID to Parse App Settings Page
4.
Replace FB.init() with Parse.FacebookUtils.init()
https://developers.facebook.com/apps
https://developers.facebook.com/docs/reference/javascript/
https://www.parse.com/apps/<your app name>/edit#authentication
37. Facebook Social Sign On
allow your Parse.Users to log in or sign up through Facebook.
Parse.FacebookUtils.logIn("user_likes,email", {
success: function(user) {
if (!user.existed()) {
// User registered through Facebook!
} else {
// User signed in through Facebook!
}
},
error: function(user, error) {
// User didn’t authorize for some reason…
}
});
You may optionally provide a comma-delimited string that specifies
what permissions your app requires from the Facebook user
https://www.parse.com/docs/js_guide#fbusers-signup
38. Facebook SDK + Node…
https://parse.com/questions/facebook-login-with-the-node-sdk-for-parse
The Facebook JavaScript SDK does not work in Node
Sign in with the Facebook Javascript SDK client side and then
transfer the credentials to the server and use REST API
39. Getting more Social
Security - roles and ACLs
Email verification and password reset
Twitter, 3rd Party Integration and Account Linking
Users in Data Browser
40. Parse Analytics
Track any data point in your app in real-time
https://www.parse.com/products/analytics
42. Custom Analytics
Track free-form events, with a handful of string keys and values
var dimensions = {
priceRange: '1000-1500',
customerType: 'renter',
age: '22-25'
};
// Send the dimensions to Parse along with the 'search' event
Parse.Analytics.track('search', dimensions);
Dimensions must
be string values
43. Check your Parse module version!
https://parse.com/questions/updates-to-the-parse-package-innpm-appear-infrequent
npm currently thinks this is the latest version
root.Parse.VERSION = "js1.2.8";
Download the actual latest version manually to get
Parse.Analytics Object
root.Parse.VERSION = "js1.2.12";
https://www.parse.com/docs/downloads
44. Parse Hosting
A powerful web presence without all the hassle.
https://www.parse.com/products/hosting
45. Parse Cloud Code
Add rich, custom logic to your app’s backend without servers.
https://www.parse.com/products/cloud_code
47. Cloud Code Project
cloud - where you cloud code snippets live
config - where your Parse app config lives
public - where static files that will be hosted live
Hosting a website with Parse is easy. Everything in the public
directory will be hosted at your-custom-subdomain.parseapp.com.
49. Cloud Functions
Cloud functions can be called from any of the client SDKs, as well as
through the REST API
Parse.Cloud.define("averageStars", function(request, response) {
var query = new Parse.Query("Review");
query.equalTo("movie", request.params.movie);
query.find({
success: function(results) {
var sum = 0;
for (var i = 0; i < results.length; ++i) {
sum += results[i].get("stars");
}
response.success(sum / results.length);
},
error: function() {
response.error("movie lookup failed");
}
});
});
Parse.Cloud.run('averageStars', {"movie":"The Matrix"}, {
success: function(result) {
// returns cloud function results
},
error: function(error) {
// returns error from cloud code
}
});
50. Cloud Functions API
•
run(key,params,callbacks) - All
•
before/afterSave(class,callbacks) - All
•
before/afterDelete(class,callbacks) - All
•
useMasterKey() - Cloud Code and Node.js only
•
define(key,callback) - Cloud Code only
•
httpRequest(options) - Cloud Code only
http://parse.com/docs/js/symbols/Parse.Cloud.html
51. Parse Express Server
After you get Parse Hosting set up, you can add dynamic backend
logic to your website by generating an Express application.
parse generate express
Creating directory /Users/nick/MyCloudCode/cloud/views
Writing out sample file /Users/nick/MyCloudCode/cloud/app.js
Writing out sample file /Users/nick/MyCloudCode/cloud/views/hello.ejs
Almost done! Please add this line to the top of your main.js:
require('cloud/app.js');
// These two lines are required to initialize Express in Cloud Code.
var express = require('express');
var app = express();
// Global app configuration section
app.set('views', 'cloud/views'); // Specify the folder to find templates
app.set('view engine', 'ejs');
// Set the template engine
app.use(express.bodyParser());
// Middleware for reading request body
// This is an example of hooking up a request handler with a specific request
// path and HTTP verb using the Express routing API.
app.get('/hello', function(req, res) {
res.render('hello', { message: 'Congrats, you just set up your app!' });
});
// Attach the Express app to Cloud Code.
app.listen();
52. Cloud Modules
Cloud Code supports breaking up JavaScript code into modules.
cloud/name.js
var coolNames = ['Ralph', 'Skippy', 'Chip', 'Ned', 'Scooter'];
exports.isACoolName = function(name) {
return coolNames.indexOf(name) !== -1;
}
cloud/main.js
var name = require('cloud/name.js');
name.isACoolName('Fred'); // returns false
name.isACoolName('Skippy'); // returns true;
name.coolNames; // undefined.
Pre-installed Cloud Modules
var Crowdflower = require('crowdflower');
Crowdflower.initialize('myAPIKey');