Parse and Cloud CodeNode.pgh - 0.16 meetup
Nicholas McClayUX Developer
@nickmcclay
What is ?
“Parse's vision is to let developers build any mobile app without
dealing with servers.”
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)
Getting Started with Parse
1. 2. 3.
Sign Up
Acquire Keys
Pick Your Platform
Sign Up with Parse
Sign Up App + Optional Info Intro Documentation
https://www.parse.com/#signup
1.
Acquire Keys
Parse Account Page
2.
Application Keys
‘Key’ Details
https://parse.com/docs/data#security-objects
• Main ID (always needed)
• iOS & Android Key
• Windows 8 & Phone Key
• Node + Client Side JS Key
• REST API Key
• ‘Sudo’ Key
Adheres to Object Level Permissions (ACL)
I choose you !
Pick Your Platform
Parse API Platforms
3.
+
yo express
npm install parse
grunt
Generate an Express App
Install Parse module
Run Server
Alternative Node-Parse Modules
npm install node-parse-api
“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 kaiseki
https://parse.com/docs/rest
A Parse.com REST API client for Node.js
Quick-Start
var Parse = require('parse').Parse; Parse.initialize(“Application ID", “JavaScript Key");
var TestObject = Parse.Object.extend("TestObject");var testObject = new TestObject();testObject.save({foo: "bar"}, { success: function(object) { alert("yay! it worked"); }});
https://parse.com/apps/quickstart#js/native/blank
Import and Initialize Parse Module
Save a “TestObject”
Parse Suite OverviewPick your problem
Parse DataStore your app’s data in the cloud. No servers necessary.
https://parse.com/products/data
Parse Data ObjectsData is schema-less
Automatic objectId, createAt and modifiedAt fields
Objects can be extended from other objects (classes)
{ objectId : "xWMyZ4YEGZ", score: 1337, playerName : "Sean Plott", cheatMode : false, createdAt : "2011-06-10T18:33:42Z", updatedAt : "2011-06-10T18:33:42Z"}
Objects can be relational
Object API
item.method({params},{callbacks})
var Class = Parse.Object.extend("ClassName"); var item = new Class();
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. } })
https://www.parse.com/docs/js_guide#objects
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
Query API
var GameScore = Parse.Object.extend("GameScore"); var query = new Parse.Query(GameScore);query.equalTo("playerEmail", “[email protected]");query.find({ success: function(object) { // Successfully retrieved the object. }, error: function(error) { // Handle error } });
https://www.parse.com/docs/js_guide#queries
Retrieve many objects at once, put conditions on the objects you wish to retrieve, and more
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
Object PointersOne-to-one and one-to-many relationships are modeled by
saving a Parse.Object as a value in the other object (pointer).
var Portfolio = Parse.Object.extend("Portfolio");var item = new Portfolio();var Comment = Parse.Object.extend("Comment");var post = new Comment(); post.save({'message' : "this is great!"},{ success : function() { item.set("comments",[post]); item.save(); }});
{ "comments": [ { "__type": "Pointer", "className": "Comment", "objectId": "YrLhRXbnfc" } ], "objectId": "Z8CarHlfu2", "createdAt": "2013-11-05T20:06:59.130Z", "updatedAt": "2013-11-05T20:06:59.130Z"}
Saving an Object pointer 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
Object Relations
var Portfolio = Parse.Object.extend("Portfolio");var item = new Portfolio();var Comment = Parse.Object.extend("Comment");var post = new Comment(); post.save({'message' : "this is great!"},{ success : function() { var relation = item.relation("comments"); relation.add(post); item.save(); }});
Many-to-many relationships are modeled using Parse.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 } });
Saving an Object relation 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.
Parse Data Browser
Lots of other Data goodness
Every asynchronous method in the Parse JavaScript SDK returns a Promise
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
Object instance and class methods
Parse PushCreating, scheduling, and segmenting push notifications
https://www.parse.com/products/push
Enabling Push Notifications
Flip this to get started
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.
Parse Channels
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 } });
Allows you to use a publisher-subscriber model for sending pushes.
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
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
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 channelquery.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
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.
Push forwardScheduling Pushes and expiration dates
Targeting by Platform and Relationships
App Notification Dashboard
Parse SocialMake your app social. Instantlyhttps://parse.com/products/data
Parse UserParse.User is a subclass of Parse.Object, and has all the same features
• username - required, makes sure username is unique
• password - required, stores as hidden hash
• email - optional, makes sure email is unique
var user = new Parse.User();user.set("username", "Nick");user.set("password", "voltan123");user.set("email", "[email protected]");// other fields can be set just like with Parse.Objectuser.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. } });
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
Setup for Facebook Integration
https://developers.facebook.com/docs/reference/javascript/
https://developers.facebook.com/apps1. Setup a Facebook App
2.
Add FB App ID to Parse App Settings Page 3.https://www.parse.com/apps/<your app name>/edit#authentication
Add Facebook JS SDK to your app
4. Replace FB.init() with Parse.FacebookUtils.init()
Facebook Social Sign On
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… }});
https://www.parse.com/docs/js_guide#fbusers-signup
You may optionally provide a comma-delimited string that specifies what permissions your app requires from the Facebook user
allow your Parse.Users to log in or sign up through Facebook.
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
Getting more Social
Security - roles and ACLs
Email verification and password reset
Users in Data Browser
Twitter, 3rd Party Integration and Account Linking
Parse AnalyticsTrack any data point in your app in real-time
https://www.parse.com/products/analytics
Complimentary AnalyticsDevelopers using Parse Data are automatically instrumented
Custom Analytics
var dimensions = { priceRange: '1000-1500', customerType: 'renter', age: '22-25'}; // Send the dimensions to Parse along with the 'search' eventParse.Analytics.track('search', dimensions);
Track free-form events, with a handful of string keys and values
Dimensions must be string values
Check your Parse module version!
root.Parse.VERSION = "js1.2.8";
root.Parse.VERSION = "js1.2.12";
npm currently thinks this is the latest version
Download the actual latest version manually to get Parse.Analytics Object
https://parse.com/questions/updates-to-the-parse-package-in-npm-appear-infrequent
https://www.parse.com/docs/downloads
Parse HostingA powerful web presence without all the hassle.
https://www.parse.com/products/hosting
Parse Cloud CodeAdd rich, custom logic to your app’s backend without servers.
https://www.parse.com/products/cloud_code
Install Cloud Code
curl -s https://www.parse.com/downloads/cloud_code/installer.sh | sudo /bin/bash
https://parse.com/docs/cloud_code_guide
parse new MyCloudCode
Email: <enter Parse.com email>
Password: <enter Parse.com password>
1:MyApp Select an App: <enter Parse App Number>
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.
Parse Deploy
parse deploy
cd MyCloudCode
Uploading source files Finished uploading files New release is named v1
Cloud Functions
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 }});
Cloud functions can be called from any of the client SDKs, as well as through the REST API
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
parse generate express
// These two lines are required to initialize Express in Cloud Code.var express = require('express'); var app = express();// Global app configuration sectionapp.set('views', 'cloud/views'); // Specify the folder to find templatesapp.set('view engine', 'ejs'); // Set the template engineapp.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();
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');
Parse Express ServerAfter you get Parse Hosting set up, you can add dynamic backend
logic to your website by generating an Express application.
Cloud Modules
var Crowdflower = require('crowdflower');Crowdflower.initialize('myAPIKey');
var coolNames = ['Ralph', 'Skippy', 'Chip', 'Ned', 'Scooter'];exports.isACoolName = function(name) { return coolNames.indexOf(name) !== -1; }
var name = require('cloud/name.js');name.isACoolName('Fred'); // returns falsename.isACoolName('Skippy'); // returns true;name.coolNames; // undefined.
cloud/name.js
cloud/main.js
Cloud Code supports breaking up JavaScript code into modules.
Pre-installed Cloud Modules
Cloud Code limitations…
Doesn’t support npm
Can’t test locally
Can’t debug…
Parse PricingPricing that scales with your needs.
http://parse.com/docs/js/
https://parse.com/docs/js_guide#javascript_guide
Getting More Help
JavaScript Guide Documentation
JavaScript SDK Documentation
https://www.parse.com/tutorialsOfficial Parse Tutorials
Thanks!
@nickmcclay