SlideShare uma empresa Scribd logo
1 de 22
Baixar para ler offline
Cloud Code Tips & Tricks
Parse London Meetup - December 4, 2013
Héctor Ramos
@hectorramos
Cloud Code Tips & Tricks
• Validating data when objects are saved.

• Performing arbitrary actions whenever objects are saved.

• Keeping client apps updated automatically in the background. 

• Scheduling long running jobs.
Cloud Code Overview
• Hosted JavaScript environment.

• Access to all your Parse Data through the JavaScript SDK.

• Perform operations on a trusted environment.

• Cloud Code deployed with parse
• Hosting included.

deploy command.
Cloud Code Overview

Save Hooks

Functions

Hosting

Background Jobs

Cloud Modules

Webhooks
Running Code Before Save
• Useful for cleaning up user-generated content.

• Validating required fields.
Business
Key
name
address

Value
“Facebook London”
“42 Earlham Street, London, WC2H 9LA”
Running Code Before Save
• Useful for cleaning up user-generated content.

• Validating required fields.
Business
Key
name
address

Business
Value
“TechOffice-FB-LON”

“42 Earlham Street, London, WC2H 9LA”

Key
name
address

Value
“Facebook London”
“42 Earlham Street, London, WC2H 9LA”

updatedAt

December 4, 2013 5:45 PM

createdAt

December 4, 2013 5:45 PM
Before Save 101

• Arbitrary code executed before an object is saved.

• Must finish within 3 seconds.
Parse.Cloud.beforeSave("Class Name", function(request, response) {
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!

var objectBeingSaved = request.object;
var userSavingThisObjectIfAny = request.user;
if (someError) {
// Reject this update. Object will not be saved.
response.error(“SomeError occurred when saving this object.”);
} else {
// Proceed with saving the object with the suggested changes, if any.
response.success();
}

});
Parse.Cloud.beforeSave("Business", function(request, response) {
// object being saved: request.object
var businessName = request.object.get("name");
!

if (businessName === "TechOffice-FB-LON") {
!

// Use the new, clean name.
request.object.put("name", "Facebook London");
!

} else if (businessName === "TechOffice-FB-MPK") {
!

request.object.put("name", "Facebook Menlo Park");
!

}
!

// Proceed with saving the object with the suggested changes, if any.
response.success();
!

});
Parse.Cloud.beforeSave("Business", function(request, response) {
// object being saved: request.object
var businessName = request.object.get("name");
var businessAddress = request.object.get("address");
!

if (!businessName) {
response.error("Validation error: name is required.");
return;
}
!

if (!businessAddress) {
response.error("Validation error: address is required.");
return;
}
!

// ... code from previous slide
response.success();
!

});
Keeping Installations in Sync with Users
Helpful later on when sending targeted push notifications.
Parse.Cloud.beforeSave(Parse.Installation, function(request, response) {
!

if (request.user) {
request.object.set(“user”, request.user);
} else {
request.object.unset(“user”);
}
!

response.success();
!

});
Performing Actions After Save
• Sending push notifications to end users

• Silently updating client side data (iOS 7)
Push Notifications After Save
1. Push notifications sent when new comments are posted.

2. App should listen for incoming push notifications.

3. Show new content in-app automatically.
Push Notifications After Save
Push notifications sent when new comments are posted.

Parse.Cloud.afterSave("Comment", function(request) {
!

// 1. Get comment details.
!

// 2. Construct notification message.
!

// 3. Define our push notification audience.
!

// 4. Deliver push notification.
});
Parse.Cloud.afterSave("Comment", function(request) {
// 1. Get comment details.
var comment = request.object;
// New comment
var fromUser = request.user;
// User who is commenting on Post
var onPost = comment.get(“post”); // Post being commented on
var postOwner = onPost.get(“owner”); // Parse.User associated with Post
// 2. Construct notification message.
var message = fromUser.getUsername() + “: “ + comment.get(“content”);
var trimmedMessage = message.substr(0, 200);
!

// 3. Define our push notification audience.
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.where(“user”, postOwner);
// 4. Deliver push notification.
Parse.Push.send({
where: pushQuery,
data: {
alert: trimmedMessage, // Message to display in Push
postId: onPost.id
// Post id for client-side retrieval
}
});
});
Push Notifications After Save
Listening to incoming push notifications
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions {
NSDictionary *pushPayload =
launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
!

}

// ...

- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
// ...
!

}
Push Guide: Responding to the Payload

https://parse.com/docs/push_guide#receiving-responding
Push Notifications After Save
Showing in-app content automatically
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSString *postId = userInfo[@“postId"];
if (postId) {
// This is a push notification for an activity over a Post object
PFObject *post = [PFObject objectWithoutDataWithClassName:@"Post"
objectId:postId];
!

// Fetch the full Post object from Parse…
[post fetchInBackgroundWithBlock:^(PFObject *post, NSError *error) {
!

}

}

// …then we display this Post with any new data in the iPhone app.
PostsViewController *postsViewController = [PostsViewController new];
postsViewController.post = post;
[self.navigationController presentViewController:postsViewController
animated:YES completion:nil];
}];
Silently Updating Clients After Save
As of iOS 7, it’s possible to trigger background refresh remotely.
Parse.Cloud.afterSave("News", function(request) {
!

var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.where("deviceType", "ios");
Parse.Push.send({
where: pushQuery,
data: {
content-available: 1
}
});
});
Updating Query Cache
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
!

PFQuery *query = [PFQuery queryWithClassName:@"News"];
query.cachePolicy = kPFCachePolicyNetworkOnly;

}

[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
completionHandler(UIBackgroundFetchResultNewData);
} else {
completionHandler(UIBackgroundFetchResultFailed);
}
}];
Background Job 101
• Long running operations, up to 15 minutes.

• Can be run on a schedule.

Parse.Cloud.job("jobName", function(request, status) {
var params = request.params;
!

status.message(“I’m running!”);
!

if (someErrorHappened) {
status.error(“The job ran into someError.”);
} else {
status.success(“The job finished successfully.”);
}
!

});
Jobs can be configured to run on a schedule

or on-demand with “Run Now”

Job status can be tracked through your Dashboard
Parse.Cloud.job("cleanupBusinessNames", function(request, status) {
var Business = Parse.Object.extend(“Business”);
var counter = 0;
!

var query = new Parse.Query(Business);
query.each().then(function(object) {
if (object.get(“name”) === “TechOffice-FB-LON”) {
object.set(“name”, “Facebook London”);
}
!

if (counter % 100 === 0) {
// Set the job's progress status every 100 loops.
status.message(counter + " businesses processed.");
}
counter += 1;
return object.save();
}).then(function() {
status.success("Done.");
}, function(error) {
status.error("Failed to update all objects.");
});
});
Q&A

Mais conteúdo relacionado

Mais procurados

OpenStack Horizon: Controlling the Cloud using Django
OpenStack Horizon: Controlling the Cloud using DjangoOpenStack Horizon: Controlling the Cloud using Django
OpenStack Horizon: Controlling the Cloud using Django
David Lapsley
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO Devs
WO Community
 
JavaScript APIs - The Web is the Platform - MDN Hack Day - Buenos Aires
JavaScript APIs - The Web is the Platform - MDN Hack Day - Buenos AiresJavaScript APIs - The Web is the Platform - MDN Hack Day - Buenos Aires
JavaScript APIs - The Web is the Platform - MDN Hack Day - Buenos Aires
Robert Nyman
 

Mais procurados (19)

Back to the 90s' - Revenge of the static website
Back to the 90s' - Revenge of the static websiteBack to the 90s' - Revenge of the static website
Back to the 90s' - Revenge of the static website
 
OpenStack Horizon: Controlling the Cloud using Django
OpenStack Horizon: Controlling the Cloud using DjangoOpenStack Horizon: Controlling the Cloud using Django
OpenStack Horizon: Controlling the Cloud using Django
 
Inside Azure Diagnostics
Inside Azure DiagnosticsInside Azure Diagnostics
Inside Azure Diagnostics
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
Intro to Core Data
Intro to Core DataIntro to Core Data
Intro to Core Data
 
Apache Cayenne for WO Devs
Apache Cayenne for WO DevsApache Cayenne for WO Devs
Apache Cayenne for WO Devs
 
Wix Automation - Core
Wix Automation - CoreWix Automation - Core
Wix Automation - Core
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gears
 
Wix Automation - DIY - Testing BI Events
Wix Automation - DIY - Testing BI EventsWix Automation - DIY - Testing BI Events
Wix Automation - DIY - Testing BI Events
 
D3_Tuto_GD
D3_Tuto_GDD3_Tuto_GD
D3_Tuto_GD
 
Rethinking Best Practices
Rethinking Best PracticesRethinking Best Practices
Rethinking Best Practices
 
jQuery Mobile Workshop
jQuery Mobile WorkshopjQuery Mobile Workshop
jQuery Mobile Workshop
 
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web AppsSenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
SenchaCon 2016: Expect the Unexpected - Dealing with Errors in Web Apps
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot Introduction
 
CloudStack S3
CloudStack S3CloudStack S3
CloudStack S3
 
Grails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to OrbitGrails Launchpad - From Ground Zero to Orbit
Grails Launchpad - From Ground Zero to Orbit
 
JavaScript APIs - The Web is the Platform - MDN Hack Day - Buenos Aires
JavaScript APIs - The Web is the Platform - MDN Hack Day - Buenos AiresJavaScript APIs - The Web is the Platform - MDN Hack Day - Buenos Aires
JavaScript APIs - The Web is the Platform - MDN Hack Day - Buenos Aires
 
"Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native ""Service Worker: Let Your Web App Feel Like a Native "
"Service Worker: Let Your Web App Feel Like a Native "
 
Anatomy of a Modern Node.js Application Architecture
Anatomy of a Modern Node.js Application Architecture Anatomy of a Modern Node.js Application Architecture
Anatomy of a Modern Node.js Application Architecture
 

Semelhante a Parse London Meetup - Cloud Code Tips & Tricks

Taking Web Apps Offline
Taking Web Apps OfflineTaking Web Apps Offline
Taking Web Apps Offline
Pedro Morais
 
Beginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCABeginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCA
Whymca
 
The Open Web and what it means
The Open Web and what it meansThe Open Web and what it means
The Open Web and what it means
Robert Nyman
 
iOS App with Parse.com as RESTful Backend
iOS App with Parse.com as RESTful BackendiOS App with Parse.com as RESTful Backend
iOS App with Parse.com as RESTful Backend
Stefano Zanetti
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
Sven Haiges
 
FI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS BasicsFI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS Basics
Petr Dvorak
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
mwbrooks
 

Semelhante a Parse London Meetup - Cloud Code Tips & Tricks (20)

Cloudbase.io MoSync Reload Course
Cloudbase.io MoSync Reload CourseCloudbase.io MoSync Reload Course
Cloudbase.io MoSync Reload Course
 
Taking Web Apps Offline
Taking Web Apps OfflineTaking Web Apps Offline
Taking Web Apps Offline
 
Developing iOS REST Applications
Developing iOS REST ApplicationsDeveloping iOS REST Applications
Developing iOS REST Applications
 
第一次用Parse就深入淺出
第一次用Parse就深入淺出第一次用Parse就深入淺出
第一次用Parse就深入淺出
 
Beginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCABeginning icloud development - Cesare Rocchi - WhyMCA
Beginning icloud development - Cesare Rocchi - WhyMCA
 
The Open Web and what it means
The Open Web and what it meansThe Open Web and what it means
The Open Web and what it means
 
Webエンジニアから見たiOS5
Webエンジニアから見たiOS5Webエンジニアから見たiOS5
Webエンジニアから見たiOS5
 
iOS App with Parse.com as RESTful Backend
iOS App with Parse.com as RESTful BackendiOS App with Parse.com as RESTful Backend
iOS App with Parse.com as RESTful Backend
 
Saving Time And Effort With QuickBase Api - Sergio Haro
Saving Time And Effort With QuickBase Api - Sergio HaroSaving Time And Effort With QuickBase Api - Sergio Haro
Saving Time And Effort With QuickBase Api - Sergio Haro
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017
 
Full Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLFull Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQL
 
iOS5 NewStuff
iOS5 NewStuffiOS5 NewStuff
iOS5 NewStuff
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
FI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS BasicsFI MUNI 2012 - iOS Basics
FI MUNI 2012 - iOS Basics
 
Leveraging parse.com for Speedy Development
Leveraging parse.com for Speedy DevelopmentLeveraging parse.com for Speedy Development
Leveraging parse.com for Speedy Development
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
 
MFF UK - Introduction to iOS
MFF UK - Introduction to iOSMFF UK - Introduction to iOS
MFF UK - Introduction to iOS
 
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
MBL301 Data Persistence to Amazon Dynamodb for Mobile Apps - AWS re: Invent 2012
 
The Hitchhikers Guide To Html5 Offline Strategies (+firefoxOS)
The Hitchhikers Guide To Html5 Offline Strategies (+firefoxOS)The Hitchhikers Guide To Html5 Offline Strategies (+firefoxOS)
The Hitchhikers Guide To Html5 Offline Strategies (+firefoxOS)
 
Node.js Patterns for Discerning Developers
Node.js Patterns for Discerning DevelopersNode.js Patterns for Discerning Developers
Node.js Patterns for Discerning Developers
 

Último

Breaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdfBreaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdf
UK Journal
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
FIDO Alliance
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
UXDXConf
 

Último (20)

Breaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdfBreaking Down the Flutterwave Scandal What You Need to Know.pdf
Breaking Down the Flutterwave Scandal What You Need to Know.pdf
 
Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024
 
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
FDO for Camera, Sensor and Networking Device – Commercial Solutions from VinC...
 
Microsoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - QuestionnaireMicrosoft CSP Briefing Pre-Engagement - Questionnaire
Microsoft CSP Briefing Pre-Engagement - Questionnaire
 
Intro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераIntro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджера
 
AI mind or machine power point presentation
AI mind or machine power point presentationAI mind or machine power point presentation
AI mind or machine power point presentation
 
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider  Progress from Awareness to Implementation.pptxTales from a Passkey Provider  Progress from Awareness to Implementation.pptx
Tales from a Passkey Provider Progress from Awareness to Implementation.pptx
 
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdfThe Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
The Value of Certifying Products for FDO _ Paul at FIDO Alliance.pdf
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!
 
(Explainable) Data-Centric AI: what are you explaininhg, and to whom?
(Explainable) Data-Centric AI: what are you explaininhg, and to whom?(Explainable) Data-Centric AI: what are you explaininhg, and to whom?
(Explainable) Data-Centric AI: what are you explaininhg, and to whom?
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024
 
Using IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & IrelandUsing IESVE for Room Loads Analysis - UK & Ireland
Using IESVE for Room Loads Analysis - UK & Ireland
 
Intro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptxIntro to Passkeys and the State of Passwordless.pptx
Intro to Passkeys and the State of Passwordless.pptx
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
2024 May Patch Tuesday
2024 May Patch Tuesday2024 May Patch Tuesday
2024 May Patch Tuesday
 
ERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage IntacctERP Contender Series: Acumatica vs. Sage Intacct
ERP Contender Series: Acumatica vs. Sage Intacct
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 

Parse London Meetup - Cloud Code Tips & Tricks

  • 1. Cloud Code Tips & Tricks Parse London Meetup - December 4, 2013 Héctor Ramos @hectorramos
  • 2. Cloud Code Tips & Tricks • Validating data when objects are saved. • Performing arbitrary actions whenever objects are saved. • Keeping client apps updated automatically in the background. • Scheduling long running jobs.
  • 3. Cloud Code Overview • Hosted JavaScript environment. • Access to all your Parse Data through the JavaScript SDK. • Perform operations on a trusted environment. • Cloud Code deployed with parse • Hosting included. deploy command.
  • 4. Cloud Code Overview Save Hooks Functions Hosting Background Jobs Cloud Modules Webhooks
  • 5. Running Code Before Save • Useful for cleaning up user-generated content. • Validating required fields. Business Key name address Value “Facebook London” “42 Earlham Street, London, WC2H 9LA”
  • 6. Running Code Before Save • Useful for cleaning up user-generated content. • Validating required fields. Business Key name address Business Value “TechOffice-FB-LON” “42 Earlham Street, London, WC2H 9LA” Key name address Value “Facebook London” “42 Earlham Street, London, WC2H 9LA” updatedAt December 4, 2013 5:45 PM createdAt December 4, 2013 5:45 PM
  • 7. Before Save 101 • Arbitrary code executed before an object is saved. • Must finish within 3 seconds. Parse.Cloud.beforeSave("Class Name", function(request, response) { ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! var objectBeingSaved = request.object; var userSavingThisObjectIfAny = request.user; if (someError) { // Reject this update. Object will not be saved. response.error(“SomeError occurred when saving this object.”); } else { // Proceed with saving the object with the suggested changes, if any. response.success(); } });
  • 8. Parse.Cloud.beforeSave("Business", function(request, response) { // object being saved: request.object var businessName = request.object.get("name"); ! if (businessName === "TechOffice-FB-LON") { ! // Use the new, clean name. request.object.put("name", "Facebook London"); ! } else if (businessName === "TechOffice-FB-MPK") { ! request.object.put("name", "Facebook Menlo Park"); ! } ! // Proceed with saving the object with the suggested changes, if any. response.success(); ! });
  • 9. Parse.Cloud.beforeSave("Business", function(request, response) { // object being saved: request.object var businessName = request.object.get("name"); var businessAddress = request.object.get("address"); ! if (!businessName) { response.error("Validation error: name is required."); return; } ! if (!businessAddress) { response.error("Validation error: address is required."); return; } ! // ... code from previous slide response.success(); ! });
  • 10. Keeping Installations in Sync with Users Helpful later on when sending targeted push notifications. Parse.Cloud.beforeSave(Parse.Installation, function(request, response) { ! if (request.user) { request.object.set(“user”, request.user); } else { request.object.unset(“user”); } ! response.success(); ! });
  • 11. Performing Actions After Save • Sending push notifications to end users • Silently updating client side data (iOS 7)
  • 12. Push Notifications After Save 1. Push notifications sent when new comments are posted. 2. App should listen for incoming push notifications. 3. Show new content in-app automatically.
  • 13. Push Notifications After Save Push notifications sent when new comments are posted. Parse.Cloud.afterSave("Comment", function(request) { ! // 1. Get comment details. ! // 2. Construct notification message. ! // 3. Define our push notification audience. ! // 4. Deliver push notification. });
  • 14. Parse.Cloud.afterSave("Comment", function(request) { // 1. Get comment details. var comment = request.object; // New comment var fromUser = request.user; // User who is commenting on Post var onPost = comment.get(“post”); // Post being commented on var postOwner = onPost.get(“owner”); // Parse.User associated with Post // 2. Construct notification message. var message = fromUser.getUsername() + “: “ + comment.get(“content”); var trimmedMessage = message.substr(0, 200); ! // 3. Define our push notification audience. var pushQuery = new Parse.Query(Parse.Installation); pushQuery.where(“user”, postOwner); // 4. Deliver push notification. Parse.Push.send({ where: pushQuery, data: { alert: trimmedMessage, // Message to display in Push postId: onPost.id // Post id for client-side retrieval } }); });
  • 15. Push Notifications After Save Listening to incoming push notifications - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions { NSDictionary *pushPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]; ! } // ... - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { // ... ! } Push Guide: Responding to the Payload https://parse.com/docs/push_guide#receiving-responding
  • 16. Push Notifications After Save Showing in-app content automatically - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSString *postId = userInfo[@“postId"]; if (postId) { // This is a push notification for an activity over a Post object PFObject *post = [PFObject objectWithoutDataWithClassName:@"Post" objectId:postId]; ! // Fetch the full Post object from Parse… [post fetchInBackgroundWithBlock:^(PFObject *post, NSError *error) { ! } } // …then we display this Post with any new data in the iPhone app. PostsViewController *postsViewController = [PostsViewController new]; postsViewController.post = post; [self.navigationController presentViewController:postsViewController animated:YES completion:nil]; }];
  • 17. Silently Updating Clients After Save As of iOS 7, it’s possible to trigger background refresh remotely. Parse.Cloud.afterSave("News", function(request) { ! var pushQuery = new Parse.Query(Parse.Installation); pushQuery.where("deviceType", "ios"); Parse.Push.send({ where: pushQuery, data: { content-available: 1 } }); });
  • 18. Updating Query Cache - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { ! PFQuery *query = [PFQuery queryWithClassName:@"News"]; query.cachePolicy = kPFCachePolicyNetworkOnly; } [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) { if (!error) { completionHandler(UIBackgroundFetchResultNewData); } else { completionHandler(UIBackgroundFetchResultFailed); } }];
  • 19. Background Job 101 • Long running operations, up to 15 minutes. • Can be run on a schedule. Parse.Cloud.job("jobName", function(request, status) { var params = request.params; ! status.message(“I’m running!”); ! if (someErrorHappened) { status.error(“The job ran into someError.”); } else { status.success(“The job finished successfully.”); } ! });
  • 20. Jobs can be configured to run on a schedule or on-demand with “Run Now” Job status can be tracked through your Dashboard
  • 21. Parse.Cloud.job("cleanupBusinessNames", function(request, status) { var Business = Parse.Object.extend(“Business”); var counter = 0; ! var query = new Parse.Query(Business); query.each().then(function(object) { if (object.get(“name”) === “TechOffice-FB-LON”) { object.set(“name”, “Facebook London”); } ! if (counter % 100 === 0) { // Set the job's progress status every 100 loops. status.message(counter + " businesses processed."); } counter += 1; return object.save(); }).then(function() { status.success("Done."); }, function(error) { status.error("Failed to update all objects."); }); });
  • 22. Q&A