Webcast Recap: Using Email to Send Push Notifications with Parse & Mailgun

Thanks to everyone who attended yesterday’s webcast, “Using Email to Send Push Notifications with Parse and Mailgun” with Parse CEO, Ilya Sukhar, and Mailgun Solutions Architect, Travis Swientek. For anyone that would like a second look, or just in case you missed it, the full video is below.

The webcast gave a step-by-step introduction on how to use email to send push notifications using Parse and Mailgun. Ilya gave everyone an overview of Parse and some interesting business cases for using email to trigger push notifications, while Travis led a deep-dive discussion covering the following topics:

  • Parse Object Storage
  • Parse Cloud Code
  • Parse iOS SDK
  • Mailgun Cloud Code Module
  • Mailgun Routes

The sample code Travis reviewed can be found on GitHub. We’ve also posted the slides on SlideShare.

Watch the video below.

Ashley Smith
January 31, 2013

What’s so great about JavaScript Promises?

tl;dr – The Parse JavaScript SDK now returns jQuery-compatible Promises from most asynchronous methods. Read on to learn what that means.

“Promises” represent the next great paradigm in JavaScript programming. But understanding why they are so great is no simple matter. At its core, a Promise represents the result of a task, which may or may not have completed. The only interface requirement of a Promise is having a function called then, which can be given callbacks to be called when the promise is fulfilled or has failed. This is outlined in the CommonJS Promises/A proposal. For example, consider saving a Parse.Object, which is an asynchronous operation. In the old callback paradigm, your code would look like this:

object.save({ key: value }, {
  success: function(object) {
    // the object was saved.
  },
  error: function(object, error) {
    // saving the object failed.
  }
});

In the new Promise paradigm, that same code would look like this:

object.save({ key: value }).then(
  function(object) {
    // the object was saved.
  },
  function(error) {
    // saving the object failed.
  });

Not much different, right? So what’s the big deal? Well, the real power of promises comes from chaining multiple of them together. Calling promise.then(func) returns a new promise, which is not fulfilled until func has completed. But there’s one really special thing about the way func is used. If a callback supplied to then returns a new promise, then the promise returned by then will not be fulfilled until the promise returned by the callback is fulfilled. The details of the behavior are explained in the Promises/A+ proposal. This is a complex topic, but maybe an example would make it clearer.

Imagine you’re writing code to log in, find an object, and then update it. In the old callback paradigm, you’d end up with what we call pyramid code:

Parse.User.logIn("user", "pass", {
  success: function(user) {
    query.find({
      success: function(results) {
        results[0].save({ key: value }, {
          success: function(result) {
            // the object was saved.
          }
        });
      }
    });
  }
});

That’s getting pretty ridiculous, and that’s without any error handling code even. But because of the way promise chaining works, the code can now be much flatter:

Parse.User.logIn("user", "pass").then(function(user) {
  return query.find();
}).then(function(results) {
  return results[0].save({ key: value });
}).then(function(result) {
  // the object was saved.
});

Ah! Much better!

Error Handling

The code samples above left out error handling for simplicity, but adding it back reiterates what a mess the old callback code could be:

Parse.User.logIn("user", "pass", {
  success: function(user) {
    query.find({
      success: function(results) {
        results[0].save({ key: value }, {
          success: function(result) {
            // the object was saved.
          },
          error: function(result, error) {
            // An error occurred.
          }
        });
      },
      error: function(error) {
        // An error occurred.
      }
    });
  },
  error: function(user, error) {
    // An error occurred.
  }
});

Because promises know whether they’ve been fulfilled or failed, they can propagate errors, not calling any callback until an error handler is encountered. For example, the code above could be written simply as:

Parse.User.logIn("user", "pass").then(function(user) {
  return query.find();
}).then(function(results) {
  return results[0].save({ key: value });
}).then(function(result) {
  // the object was saved.
}, function(error) {
  // there was some error.
});

Generally, developers consider a failing promise to be the asynchronous equivalent to throwing an exception. In fact, if a callback passed to then throws an error, the promise returned will fail with that error. Propagating the error to the next available error handler is the asynchronous equivalent to bubbling up an exception until a catch is encountered.

jQuery, Backbone, and Parse

There are plenty of implementations of promises available to developers. For example, jQuery’s Deferred, Microsoft’s WinJS.Promise, when.js, q, and dojo.Deferred.

However, there is one interesting corner case to be aware of. As you can read in this long and fascinating jQuery pull request discussion, jQuery’s implementation does not quite fulfill the Promises/A spec in the way that most of the other implementations do. Experimentally, there’s only one case I’ve found where they actually diverge. If an error handler returns something other than a promise, most implementations consider the error handled, and don’t propagate it. However, jQuery does not consider the error handled in these cases, and propagates it forward anyway. While intermixing promises from different systems should normally work seamlessly, you should keep an eye out for this scenario. One potential workaround is to always return promises from your error handlers (instead of raw values), since they are always treated the same.

doFailingAsync().then(function() {
  // doFailingAsync doesn't succeed.
}, function(error) {
  // Try to handle the error.
  return "It's all good.";
}).then(function(result) {
  // Non-jQuery implementations will reach this with result === "It's all good.".
}, function(error) {
  // jQuery will reach this with error === "It's all good.".
});

In the latest release of Backbone 0.9.10, the asynchronous methods now return a jqXHR, which is a type of jQuery promise. One of the goals of the Parse JavaScript SDK is to maintain compatibility with Backbone as much as possible. We cannot return a jqXHR, because that wouldn’t work well in Cloud Code. So, we have added a class called Parse.Promise, which conforms to the jQuery Deferred semantics. In the latest version of the Parse JavaScript SDK, we have upgraded all of our asynchronous methods to return these new objects. The old callbacks are still accepted. But based on the examples listed above, we think you’ll prefer the new way. So give promises a try!

Update: Check out the new Promises guide, which has more explanations and examples, here: https://parse.com/docs/js_guide#promises

Bryan Klimt
January 29, 2013

10 Best Practices for Incorporating Transactional Email into Your Apps

cornhole
One of our biggest goals at Parse is to provide our developers with all of the tools that they could possibly need or want when creating powerful apps. From data storage to social integration, we want it to be easy for you to integrate the most up-to-date features into your mobile and desktop applications. That’s why we partnered with SendGrid, MailChimp, and Mailgun to bring you email tools, including transactional email, for your app via our Cloud Modules.

Transactional Email: What is it?

Any email your app or website sends on your behalf, from receipts to registration confirmations and “you have a new follower” announcements to “you have safely unsubscribed” messages. Our Cloud Module friends over at MailChimp have done an impressive job of breaking it down for those of you who are unfamiliar.

Okay, I want it. Now how do I do it right?

 

    • DO personalize your emails. Most email provider programs offer the functionality to personalize emails sent to customers with their names. Use this feature! It helps keep your users engaged and makes the email feel less cold and impersonal.
    • DON’T let your transactional emails be an afterthought. These emails are an extension of your product, and are linked to your app in users’ minds. Take the opportunity to maintain your brand rather than throwing away this connection to your customers as an unimportant “necessary evil.” Many of these emails ARE necessary, so why not make them awesome?
    • But DO keep it simple. Since transactional emails are often the result of a user request (password re-sets, receipts, update notifications), you want to make sure they’re actually making it to your customers’ inboxes and being read. Keep the HTML simple and clean and the message to the point.

re-set password email

  • DO spell check and edit your emails and templates. Smart apps have smart users – make sure your emails are grammatically correct and spelling-error free. Don’t just assume that because it’s a receipt or other transactional email, the customer won’t be reading the whole thing. Properly written emails inspire confidence from your users and show that you pay attention to details.
  • DO avoid spam triggers. Avoid all caps, lots of exclamation points, excessive use of images and other common traps. Remember, you want your customers to actually receive and read these emails.
  • DO make sure your emails are easily viewable on mobile devices. You made a mobile app, now make sure your transactional emails are compatible with mobile devices. More and more people are checking their email on their mobile devices every day, and our friends at SendGrid have some great tips for maximizing their experience here.
  • DO make it easy for your customers to respond to transactional email. Include an easy to find “Unsubscribe” button or link and make it clear how the customer can get in touch if they have questions or feel that the email was sent in error or has a mistake. “Do not reply to this email” is not friendly and will not engender love for your app in your customers. Making transactional emails easy to respond to also makes them seem more personal and therefore increases the likelihood that they’ll be opened in the future.
  • DO use the opportunity to carefully market to your users. We already pointed out that these emails are important because your users are expecting them, but that fact also means they present a unique marketing opportunity. Since customers expect these emails, they’re much more likely to open them. You can seize this opportunity by discreetly including marketing messages for new-but-similar products, offer codes, and other content related to the transactional email message that you’d like customers to see. The trick here is to keep it related to the email’s message, so it doesn’t seem like a jarring marketing ploy.
  • DO use the innovative tools developed by email sending systems. Mandrill by MailChimp offers click-through tracking and other analytics to help you perfect your transactional emails. SendGrid provides a cloud-based email infrastructure that relieves businesses of the cost and complexity of maintaining custom email systems. Mailgun is a set of powerful APIs that allow you to send, receive, track and store email effortlessly as well as allowing you to send Push notifications via email.
  • DO monitor your transactional emails’ delivery and success rates. Transactional emails get sent as the result of an action, either from your users, directed at them by other users, or the app. If these emails aren’t getting to customers’ inboxes you have a problem that needs fixing, and the only way you’re going to know if that’s the case is by monitoring delivery and success rates. Many email programs offer this functionality, so make sure you’re taking advantage of it.
Courtney Witmer
January 28, 2013

Jukely, Your Personal Concert Concierge, Gets You on the List

Jukely on iphone

You know that friend that always has tickets to the hottest concert in town after it’s already been sold out? Are you the person that didn’t know the cool new hipster band was in town until after you saw other people’s Instagram pictures of the concert? Well fret no more my friends; with the newly launched Parse-powered app, Jukely, you’ll not only know about any noteworthy upcoming shows, you’ll also be able to add your name to the guest list in one fell swoop.

App co-founder Bora Celik tells us how the innovative new app came about, and how Parse factored into its development.

Tell us about yourself.

I’m the co-founder and the developer of the Jukely (the iPhone app) as well as the back-end API.

And what can you tell us about Jukely?

Jukely is a personal live music concierge. It learns from your and your friends’ music tastes, makes show recommendations and gets you on the guest list when you want to go.

Sounds brilliant; how did you come up with that idea?

I used to work as a concert organizer for many years and experienced very closely the challenges of connecting the right people with the right shows. From a music lover perspective, my co-founder Andrew Cornett and I love going to shows and discovering new artists without planning too far out. We wanted to build a solution that allowed us to find out what we might like that’s happening tonight or in a few days and we didn’t want to deal with painful ticket purchasing processes that made us use archaic things like a printer.

What led you to Parse?

I came across Parse when I was reading an article last spring about an easy way to build a back-end to mobile apps.

How is it used in Jukely?

Our iPhone app is built using RubyMotion and the Parse iOS library. Our back-end recommendations API is in Ruby and uses the Parse REST API. Of course all of our data is stored in Parse.

What have been the key benefits of working with Parse?

We’re a two-person team and I did almost all of the development, so time and resources were a real factor in getting our app out. Our main focus has always been a great UI and focusing on the user experience.

I’ve done startups before that built iOS apps and I know how much longer it takes to build one due to additional complexities the platform introduces. The most inviting piece of Parse was its excellent iOS library. Using it allowed us to skip writing our own code to do things like loading and saving things using background processing, signup, login, Facebook/Twitter integrations, push notifications, file uploads, as well as having image loading in tables working smoothly out of the box.

Of course using the easy Parse REST API and database provided additional time savings as we didn’t need to build and maintain our own database. I would imagine compared to my previous “iOS app with a back-end API” development experiences, this saved us time that can be measured in months.

Jukely launched on Monday, January 21 with service to the New York City area.

Courtney Witmer
January 24, 2013

Summary of the January 22nd Parse Service Disruption

We would like to share more details about the nature of the events during the January 22nd service disruption. We are working hard to improve reliability and would like to relay information about the nature of the service disruption, our efforts to restore functionality, and the steps we are taking to prevent this sort of issue from happening again.

The initial outage began at 8:16 A.M. PST and was related to a routine operation that involved rotating nodes to defragment and compact our database. This triggered a rare edge case in Cloud Code which caused all Cloud Code requests to simultaneously time out, which in turn caused a timeout feedback loop at the app server layer. In the process of restoring service, we also discovered that some indexes had been incorrectly built on one instance. This delayed our ability to recover quickly. Service was fully restored at 9:24 A.M.

In response to this incident, we have taken the following steps:

  • We are adding more sanity checks and safeguards around our routine database maintenance tasks and migrations.
  • We are adding significantly more monitoring around Cloud Code capacity and handling for unusual error states.
  • We are improving our ability to selectively target Parse functionality, so the impact of any performance degradation is localized and does not affect the majority of Parse apps.
  • We are adding post hoc analysis of smart indexing to catch any edge cases.

We apologize for the outage. We built this platform for engineers like ourselves and know that a platform outage can be terribly disruptive for our customers. Rest assured, the entire team here is committed to the long term stability of the platform and works hard to avoid such events. If you have any questions, please reach out to us through our Help & Community portal.

Charity Majors
January 23, 2013

Got .NET? Parse Now Supports .NET 4.5

Parse .NET SDK

Whether you’re building a web application using ASP.NET or a rich client application for using WPF, .NET offers a powerful platform to build upon.  Today, we’re excited to introduce support for .NET 4.5 from our Windows SDK, making it easy to target a wide range of platforms including Windows 7 and Windows Server.

As always, we’re committed to providing a great development experience tailored to the platforms we support, so we’ve made sure to support modern .NET features such as LINQ and async/await:

// Build a query
var query = from post in ParseObject.GetQuery("Post")
            where post["author"] == ParseUser.CurrentUser
            orderby post.CreatedAt descending
            select post;

// Retrieve the results
IEnumerable<ParseObject> postsByUser = await query.FindAsync();

Now you have all the power of Parse at your fingertips when building .NET-based applications, allowing you to avoid maintaining a database for yourself and granting you easy access to powerful features such as file storage, user management, role-based access controls, Facebook authentication, rich queries, and Cloud Code.

You can quickly add the Parse SDK to your applications today using NuGet in Visual Studio. Take a look at our Windows Guide and Windows Quickstart to start using Parse today!

David Poll
January 23, 2013

Sobrio App Looks to Reduce Drinking and Driving with Easy Access to Designated Drivers

sobrio on iphone

In the US, at age 21, many of us were (or are, or plan to be) enrolled in college, attending classes, maybe working a job or two, and enjoying our newly-minted drinking-age. Most of us aren’t out there trying to solve the problems of our generation, on top of all those other time-consuming activities. Thankfully for the rest of us, University of Connecticut students Tom Bachant and Naday Ullman are out there thinking up those solutions on our behalf. Their Parse-powered app, Sobrio, helps designated drivers within a community effectively connect with those in need of a ride so that everyone gets home safely.

The app, which operates similarly to San Francisco based start-ups Lyft and Sidecar, seeks to reduce drinking and driving by providing a convenient way to exchange safe rides. The app helps designated drivers in a group or area organize their pick-up schedule for the night and keeps those in need of a ride updated on when to expect a pick-up. The riders can then reward the Good Samaritan drivers with tips via the app.

We sat down with Tom to get his run-down of how Sobrio came to be, as well as his experiences with Parse.

Tell us a little bit about yourself.

I’m a 21-year old senior studying Biomedical engineering. I first started programming my freshman year of college through work-study, making iPhone apps even though I had never done it before. It turned from a job to a hobby, and now back to a job again! I really enjoy building new things, and programming is the perfect way to have the freedom to create. In addition to being the co-founder of Sobrio and a full-time student, I am the lead iOS developer at Groupcentric (groupcentric.com), and I develop my own apps independently.

Where did the idea for Sobrio originate?

My co-founder, Nadav Ullman, another student at UConn, first proposed the idea for the app. We noticed that being a designated driver on a college campus was a chaotic experience. A driver’s cell phone would be ringing off the hook with other students looking for rides, and there was no way to organize their night. Similarly, people who needed these rides had no way of telling when or if their ride was coming. With Sobrio, the driver can easily manage all of their rides for the evening, and the rider can instantly see when their ride is coming. What’s great is that someone who needs a ride one night can become a driver the next night and return the favor.

To ensure safety, this is all done within private groups. For example, a university group only allows students for that school to join. People can also create their own password-protected groups, which we’ve found is helpful for organizations like fraternities, sports teams, and even office carpools to exchange rides.

Once you had the idea, how did you end up using Parse?

A friend first referred me to Parse during the early stages of Sobrio. I had never built a server or touched SQL before, so I gave it a shot. It was so easy to setup and get started that I never looked back.

How is Parse used in the app?

Parse is used to store and retrieve our data for every ride that takes place. It was easy to get the database up and running to start saving objects, making queries, and sending push notifications.

You mentioned using Parse for push; how does that factor into Sobrio?

Sobrio takes full advantage of the powerful push notifications system on Parse. We use pushes to alert drivers when someone needs a ride, to alert riders when their ride has been offered, and to provide a convenient messaging system between the users.

What do you love most about Parse?

It’s hard to pick one thing that I love most about Parse, but I have to say that the convenience of step-by-step instructions let me get Sobrio up and running in half the time (and half the frustration) it would’ve taken otherwise. Plus, the support team is always there to help whenever I have a specific question.

Sobrio launched as an iOS app at the University of Connecticut in September, and is on pace to hit their 1,000th ride shared soon. They’re currently in the process of developing an Android application, due out later in the spring semester, and are looking to bring Sobrio to college campuses across the country.

Courtney Witmer
January 21, 2013

Register for the Webcast: Using Email to Send Push Notifications with Parse and Mailgun

Following our partnership with Mailgun to launch the Mailgun Cloud Module, we’re proud to announce a joint webcast scheduled for January 30th, 2013 at 10:30 AM PST.

In this webcast, participants will learn how to use email to send push notifications using Parse and Mailgun. Ilya Sukhar, Parse CEO, will give a quick intro to Parse functionality followed by a deep dive technical discussion and live-coding session. Travis Swientek from Mailgun will lead the tech talk and will cover the following topics:

  • Parse Object Storage
  • Parse Cloud Code
  • Parse IOS SDK
  • Mailgun Cloud Code Module
  • Mailgun Routes

Following the webcast, registrants will receive a link to a recording of the tech talk as well as a link to the code repository on GitHub. There will also be a Q&A session at the end of the webcast.

More about Mailgun – Mailgun is the email automation engine trusted by over 10,000 companies worldwide including Parse, Stripe and Uservoice. Mailgun’s intuitive REST API’s let you easily send, receive and track emails through your web apps and websites. Mailgun is way more than email delivery. It is complete email automation.

To view the re-cap of “Using Email to Send Push Notifications with Parse and Mailgun”, please click here.

Ashley Smith
January 15, 2013

Please Join Us for Renaissance: The iOS App Makers’ Conference with 30% Off Tickets

Screen Shot 2013-01-14 at 3.48.33 PM

The Parse team will be hosting a booth at Renaissance: the iOS app makers’ conference in San Francisco next Monday through Wednesday (January 21-23) and we’d love to see you there! We’ve donated 3 six-month Parse Pro packages (each valued at $1200) to be given away as prizes during the event, and we’ll be on site to answer any questions that you or your dev team might have.

Renaissance is, “bringing the best of the iOS app making community together to teach us to excel at the business, design, and technology of apps,” and will include speakers from Stripe, Quora, Square and more. Join us and save 30% here: http://renaissance2013.eventbrite.com/?discount=parse

Courtney Witmer
January 15, 2013

Hello, NSPredicate

Here at Parse, we believe that the frameworks you use to build your app should conform to your needs, not the other way around. That’s why we build native SDKs for all the platforms we support. And we integrate with unique features on each platform to make using our API feel right at home. For example, in JavaScript, we integrate with Backbone. On Windows, we support LINQ. Today, I’d like to tell you about a recent addition to this menagerie. On iOS and Mac OS X, we’ve added support for creating a PFQuery using NSPredicate and NSSortDescriptor. If you don’t know about NSPredicate and NSSortDescriptor, or just prefer the normal PFQuery methods, no need to worry. This isn’t replacing the old methods. In fact, to get the most out of PFQuery, we still recommend using the rest of its methods. However, for those of you who prefer NSPredicate, it’s a fine alternative. For example:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"playerName = 'Dan Stemkosk'"];
PFQuery *query = [PFQuery queryWithClassName:@"GameScore" predicate:predicate];
[query orderBySortDescriptor:[NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO]];

At this time, we support these NSPredicate features:

  • Simple comparisons such as =, !=, <, >, <=, >=, and BETWEEN with a key and a constant.
  • Containment predicates, such as x IN {1, 2, 3}.
  • Key-existence predicates, such as x IN SELF.
  • BEGINSWITH expressions.
  • Compound predicates with AND, OR, and NOT.
  • Sub-queries with "key IN %@", subquery.

See our docs for more details and examples.

Bryan Klimt
January 14, 2013

Archives

Categories

RSS Feed Follow us Like us