+ All Categories
Home > Documents > Parse Android Guid

Parse Android Guid

Date post: 10-Mar-2016
Category:
Upload: avinash-kumar-sharma
View: 18 times
Download: 0 times
Share this document with a friend
Description:
parse api

of 196

Transcript
  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    AndroidGuide Browse

    Android Guide Browse all platforms Browse

    Getting StartedIf you haven't installed the SDK yet, please head over tothe QuickStart guide to get our SDK up and running inAndroid Studio. Note that we support Android 2.3 andhigher. You can also check out our API Reference formore detailed information about our SDK.

    The Parse platform provides a complete backendsolution for your mobile application. Our goal is tototally eliminate the need for writing server code ormaintaining servers. If you're familiar with webframeworks like Ruby on Rails, we've taken many of thesame principles and applied them to our platform. Inparticular, our SDK is ready to use out of the box withminimal conguration on your part.

    On Parse, you create an App for each of your mobileapplications. Each App has its own application id andclient key that you apply to your SDK install. Youraccount on Parse can accommodate multiple Apps. Thisis useful even if you have one application, since you candeploy dierent versions for test and production.

    Want to contribute to this doc? Edit this section.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Was this section helpful? NOYES

    ObjectsThe ParseObject

    Storing data on Parse is built around the .Each contains key-value pairs of JSON-compatible data. This data is schemaless, which meansthat you don't need to specify ahead of time what keysexist on each . You simply set whateverkey-value pairs you want, and our backend will store it.

    For example, let's say you're tracking high scores for agame. A single could contain:

    Keys must be alphanumeric strings. Values can bestrings, numbers, booleans, or even arrays and objects -anything that can be JSON-encoded.

    Each has a class name that you can use todistinguish dierent sorts of data. For example, wecould call the high score object a . Werecommend that you NameYourClassesLikeThis andnameYourKeysLikeThis, just to keep your code lookingpretty.

    Saving Objects

    Let's say you want to save the describedabove to the Parse Cloud. The interface is similar to a , plus the method:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    After this code runs, you will probably be wondering ifanything really happened. To make sure the data wassaved, you can look at the Data Browser in your app onParse. You should see something like this:

    There are two things to note here. You didn't have tocongure or set up a new Class called beforerunning this code. Your Parse app lazily creates thisClass for you when it rst encounters it.

    There are also a few elds you don't need to specifythat are provided as a convenience. is aunique identier for each saved object. and represent the time that each object wascreated and last modied in the cloud. Each of theseelds is lled in by Parse, so they don't exist on a until a save operation has completed.

    Retrieving Objects

    Saving data to the cloud is fun, but it's even more fun toget that data out again. If you have the , youcan retrieve the whole using a :

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    To get the values out of the , there's a method for each data type:

    If you don't know what type of data you're getting out,you can call , but then you probably have tocast it right away anyways. In most situations youshould use the typed accessors like .

    The three special values have their own accessors:

    If you need to refresh an object you already have withthe latest data that is in the cloud, you can call the method like so:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    The code in the will be run on the mainthread.

    The Local Datastore

    Parse also lets you store objects in a local datastore onthe Android device itself. You can use this for data thatdoesn't need to be saved to the cloud, but this isespecially useful for temporarily storing data so that itcan be synced later. To enable the datastore, call in your constructor before calling . Oncethe local datastore is enabled, you can store an objectby pinning it.

    As with saving, this recursively stores every object andle that points to, if it has been fetched fromthe cloud. Whenever you save changes to the object, orfetch new changes from Parse, the copy in thedatastore will be automatically updated, so you don't

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    have to worry about it.

    Retrieving Objects from the Local

    Datastore

    Storing an object is only useful if you can get it backout. To get the data for a specic object, you can use a just like you would while on the network,but using the method to tell itwhere to get the data.

    If you already have an instance of the object, you caninstead use the method.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Unpinning Objects

    When you are done with the object and no longer needto keep it on the device, you can release it with .

    Saving Objects Offline

    Most save functions execute immediately, and informyour app when the save is complete. If you don't needto know when the save has nished, you can use instead. The advantage is that if theuser currently doesn't have a network connection, will store the update on the device untila network connection is re-established. If your app isclosed before the connection is back, Parse will tryagain the next time the app is opened. All calls to (and ) are executed inthe order they are called, so it is safe to call on an object multiple times. If you havethe local datastore enabled, then any object you will be pinned as long as that save is inprogress. That makes it easy to retrieve your localchanges while waiting for the network to be available.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Updating Objects

    Updating an object is simple. Just set some new dataon it and call one of the save methods. Assuming youhave saved the object and have the , you canretrieve the using a and updateits data:

    Parse automatically gures out which data has changedso only "dirty" elds will be transmitted during a save.You don't need to worry about squashing data in thecloud that you didn't intend to update.

    Counters

    The above example contains a common use case. The

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    "score" eld is a counter that we'll need to continuallyupdate with the player's latest score. Using the abovemethod works but it's cumbersome and can lead toproblems if you have multiple clients trying to updatethe same counter.

    To help with storing counter-type data, Parse providesmethods that atomically increment (or decrement) anynumber eld. So, the same update can be rewritten as:

    You can also increment by any amount using .

    Arrays

    To help with storing array data, there are threeoperations that can be used to atomically change anarray eld:

    For example, we can add items to the set-like "skills"eld like so:

    and append the given objects to theend of an array eld.

    and add only the givenobjects which aren't already contained in an arrayeld to that eld. The position of the insert is notguaranteed.

    removes all instances of the givenobjects from an array eld.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Note that it is not currently possible to atomically addand remove items from an array in the same save. Youwill have to call in between every dierent kind ofarray operation.

    Deleting Objects

    To delete an object from the Parse Cloud:

    If you want to run a callback when the delete isconrmed, you can provide a to the method. If you want to block thecalling thread, you can use the method.

    You can delete a single eld from an object with the method:

    Relational Data

    Objects can have relationships with other objects. Tomodel this behavior, any can be used as avalue in other s. Internally, the Parseframework will store the referred-to object in just oneplace, to maintain consistency.

    For example, each in a blogging app mightcorrespond to one . To create a new with asingle , you could write:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    You can also link objects using just their s likeso:

    By default, when fetching an object, relateds are not fetched. These objects' valuescannot be retrieved until they have been fetched like so:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    You can also model a many-to-many relation using the object. This works similar to , except that you don't need todownload all the s in a relation at once. Thisallows to scale to many more objectsthan the approach. For example, a may have many s that they might like. In thiscase, you can store the set of s that a likesusing . In order to add a post to the list, thecode would look something like:

    You can remove a post from the withsomething like:

    By default, the list of objects in this relation are notdownloaded. You can get the list of s by calling on the returned by . The code would look like:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    If you want only a subset of the s you can addextra constraints to the returned by . The code would look something like:

    For more details on , please look at thequery portion of this guide. A behavessimilar to a for querying purposes,so any queries you can do on lists of objects (other than ) you can do on .

    Data Types

    So far we've used values with type , , ,and . Parse also supports ,and .

    You can nest and objects tostore more structured data within a single .

    Some examples:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    We do not recommend storing large pieces of binarydata like images or documents using elds on . s should not exceed 128kilobytes in size. To store more, we recommend you use . See the guide section for more details.

    For more information about how Parse handles data,check out our documentation on Data.

    Subclasses

    Parse is designed to get you up and running as quicklyas possible. You can access all of your data using the class and access any eld with . Inmature codebases, subclasses have many advantages,including terseness, extensibility, and support forautocomplete. Subclassing is completely optional, butcan transform this code:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Into this:

    S U B C L A S S I N G P A R S E O B J E C T

    To create a subclass:

    Declare a subclass which extends .1

    Add a annotation. Its valueshould be the string you would pass into the constructor, and makes all futureclass name references unnecessary.

    2

    Ensure that your subclass has a public default (i.e.zero-argument) constructor. You must notmodify any elds in this constructor.

    3

    Callin your constructor before calling . The following codesucessfully implements and registers the subclass of :

    4

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    A C C E S S O R S , M U T A T O R S , A N D M E T H O D S

    Adding methods to your subclass helpsencapsulate logic about the class. You can keep all yourlogic about a subject in one place rather than usingseparate classes for business logic andstorage/transmission logic.

    You can add accessors and mutators for the elds ofyour easily. Declare the getter and setterfor the eld as you normally would, but implementthem in terms of and . The followingexample creates a eld in the class:

    You can now access the displayName eld using and assign to it using . This allows yourIDE to provide autocompletion as you develop your app

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    and allows typos to be caught at compile-time.

    Accessors and mutators of various types can be easilydened in this manner using the various forms of such as , , or .

    If you need more complicated logic than simple eldaccess, you can declare your own methods as well:

    I N I T I A L I Z I N G S U B C L A S S E S

    You should create new instances of your subclassesusing the constructors you have dened. Your subclassmust dene a public default constructor that does notmodify elds of the , which will be usedthroughout the Parse SDK to create strongly-typedinstances of your subclass.

    To create a reference to an existing object, use :

    Q U E R I E S

    You can get a query for objects of a particular subclassusing the static method . Thefollowing example queries for armors that the user canaord:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Was this section helpful? NOYES

    Want to contribute to this doc? Edit this section.

    QueriesWe've already seen how a with can retrieve a single fromParse. There are many other ways to retrieve data with - you can retrieve many objects at once, putconditions on the objects you wish to retrieve, cachequeries automatically to avoid writing that codeyourself, and more.

    Basic Queries

    In many cases, isn't powerful enoughto specify which objects you want to retrieve. The oers dierent ways to retrieve a list ofobjects rather than just a single object.

    The general pattern is to create a , putconditions on it, and then retrieve a of matching

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    s using the method witha . For example, to retrieve scores with aparticular , use the method toconstrain the value for a key:

    works similarly to inthat it assures the network request is done on abackground thread, and runs its callback in the mainthread.

    Query Constraints

    There are several ways to put constraints on theobjects found by a . You can lter outobjects with a particular key-value pair with :

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    You can give multiple constraints, and objects will onlybe in the results if they match all of the constraints. Inother words, it's like an AND of constraints.

    You can limit the number of results with . Bydefault, results are limited to 100, but anything from 1to 1000 is a valid limit:

    If you want exactly one result, a more convenientalternative may be to use or instead of using .

    You can skip the rst results with . This can be

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    useful for pagination:

    For sortable types like numbers and strings, you cancontrol the order in which results are returned:

    You can add more sort keys to the query as follows:

    For sortable types, you can also use comparisons inqueries:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    If you want to retrieve objects matching severaldierent values, you can use ,providing a collection of acceptable values. This is oftenuseful to replace multiple queries with a single query.For example, if you want to retrieve scores made by anyplayer in a particular list:

    If you want to retrieve objects that do not match any ofseveral values you can use ,providing an array of acceptable values. For example, ifyou want to retrieve scores from players besides thosein a list:

    If you want to retrieve objects that have a particular keyset, you can use . Conversely, if you want toretrieve objects without a particular key set, you canuse .

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    You can use the method to getobjects where a key matches the value of a key in a setof objects resulting from another query. For example, ifyou have a class containing sports teams and you storea user's hometown in the user class, you can issue onequery to nd the list of users whose hometown teamshave winning records. The query would look like:

    Conversely, to get objects where a key does not matchthe value of a key in a set of objects resulting fromanother query, use . Forexample, to nd users whose hometown teams havelosing records:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    You can restrict the elds returned by calling with a collection of keys. To retrievedocuments that contain only the and elds (and also special built-in elds such as , , and ):

    The remaining elds can be fetched later by calling oneof the variants on the returned objects:

    Queries on Array Values

    If a key contains an array value, you can search for

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    objects where the key's array value contains 2 by:

    You can also search for objects where the key's arrayvalue contains each of the values 2, 3, and 4 with thefollowing:

    Queries on String Values

    Use to restrict to string values thatstart with a particular string. Similar to a MySQL LIKEoperator, this is indexed so it is ecient for largedatasets:

    If you're trying to implement a generic search feature, werecommend taking a look at this blog post:Implementing Scalable Search on a NoSQL Backend.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    The above example will match any objects where the value in the "name" String key startswith "Big Daddy's". For example, both "Big Daddy's" and"Big Daddy's BBQ" will match, but "big daddy's" or"BBQ Sauce: Big Daddy's" will not.

    Queries that have regular expression constraints arevery expensive. Refer to the Performance Guide formore details.

    Relational Queries

    There are several ways to issue queries for relationaldata. If you want to retrieve objects where a eldmatches a particular , you can use just like for other data types. Forexample, if each has a object in its eld, you can fetch comments for a particular :

    If you want to retrieve objects where a eld contains a that matches a dierent query, you canuse . Note that the default limit of100 and maximum limit of 1000 apply to the innerquery as well, so with large data sets you may need toconstruct queries carefully to get the desired behavior.In order to nd comments for posts containing images,

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    you can do:

    If you want to retrieve objects where a eld contains a that does not match a dierent query, youcan use . In order to ndcomments for posts without images, you can do:

    In some situations, you want to return multiple types of

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    related objects in one query. You can do this with the method. For example, let's say you areretrieving the last ten comments, and you want toretrieve their related posts at the same time:

    You can also do multi level includes using dot notation.If you wanted to include the post for a comment andthe post's author as well you can do:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    You can issue a query with multiple elds included bycalling multiple times. This functionality alsoworks with ParseQuery helpers like and .

    Querying the Local Datastore

    If you have enabled the local datastore by calling before your call to , then you can also query againstthe objects stored locally on the device. To do this, callthe method on the query.

    You can query from the local datastore using exactlythe same kinds of queries you use over the network.The results will include every object that matches thequery that's been pinned to your device. The queryeven takes into account any changes you've made tothe object that haven't yet been saved to the cloud. Forexample, if you call , on an object, itwill no longer be returned from these queries.

    Caching Queries

    It's often useful to cache the result of a query on a

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    device. This lets you show data when the user's deviceis oine, or when the app has just started and networkrequests have not yet had time to complete. Theeasiest way to do this is with the local datastore. Whenyou pin objects, you can attach a label to the pin, whichlets you manage a group of objects together. Forexample, to cache the results of the query above, youcan call and give it a label.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Now when you do any query with ,these objects will be included in the results if they stillmatch the query.

    If you aren't using the local datastore, you can use theper-query cache for instead. The defaultquery behavior doesn't use the cache, but you canenable caching with . For example, to trythe network and then fall back to cached data if thenetwork is not available:

    Parse provides several dierent cache policies:

    : The query does not load from thecache or save results to the cache. is the default cache policy.

    : The query only loads from the cache,ignoring the network. If there are no cachedresults, that causes a . : The query does not load from the

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    If you need to control the cache's behavior, you can usemethods provided in ParseQuery to interact with thecache. You can do the following operations on thecache:

    Query caching also works with ParseQuery helpers

    : The query does not load from thecache, but it will save results to the cache.

    : The query rst tries to loadfrom the cache, but if that fails, it loads resultsfrom the network. If neither cache nor networksucceed, there is a .

    : The query rst tries to loadfrom the network, but if that fails, it loads resultsfrom the cache. If neither network nor cachesucceed, there is a .

    : The query rst loads fromthe cache, then loads from the network. In thiscase, the will actually be calledtwice - rst with the cached results, then with thenetwork results. This cache policy can only beused asynchronously with .

    Check to see if there is a cached result for thequery with:

    Remove any cached results for a query with:

    Remove cached results for all queries with:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    including and .

    Counting Objects

    Caveat: Count queries are rate limited to a maximum of160 requests per minute. They can also returninaccurate results for classes with more than 1,000objects. Thus, it is preferable to architect yourapplication to avoid this sort of count operation (byusing counters, for example.)

    If you just need to count how many objects match aquery, but you do not need to retrieve all the objectsthat match, you can use instead of . Forexample, to count how many games have been playedby a particular player:

    If you want to block the calling thread, you can also usethe synchronous method.

    Compound Queries

    If you want to nd objects that match one of several

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    queries, you can use method toconstruct a query that is an or of the queries passed in.For instance if you want to nd players who either havea lot of wins or a few wins, you can do:

    You can add additional constraints to the newly created that act as an 'and' operator.

    Note that we do not, however, support GeoPoint ornon-ltering constraints (e.g. , , , , , ) in the subqueriesof the compound query.

    Want to contribute to this doc? Edit this section.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Was this section helpful? NOYES

    UsersAt the core of many apps, there is a notion of useraccounts that lets users access their information in asecure manner. We provide a specialized user classcalled that automatically handles much ofthe functionality required for user accountmanagement.

    With this class, you'll be able to add user accountfunctionality in your app.

    is a subclass of the , and has allthe same features, such as exible schema, automaticpersistence, and a key value interface. All the methodsthat are on also exist in . Thedierence is that has some special additionsspecic to user accounts.

    Properties

    has several properties that set it apart from :

    We'll go through each of these in detail as we runthrough the various use cases for users. Keep in mindthat if you set and using the setters,you do not need to set it using the method.

    Signing Up

    The rst thing your app will do is probably ask the user

    username: The username for the user (required).

    password: The password for the user (requiredon signup).

    email: The email address for the user (optional).

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    to sign up. The following code illustrates a typical signup:

    This call will asynchronously create a new user in yourParse App. Before it does this, it checks to make surethat both the username and email are unique. Also, itsecurely hashes the password in the cloud using bcrypt.We never store passwords in plaintext, nor will we evertransmit passwords back to the client in plaintext.

    Note that we used the method, notthe method. New s shouldalways be created using the (or ) method. Subsequent updates to a user can bedone by calling .

    The method comes in variousavors, with the ability to pass back errors, and alsosynchronous versions. As usual, we highly recommend

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    using the asynchronous versions when possible, so asnot to block the UI in your app. You can read moreabout these specic methods in our API docs.

    If a signup isn't successful, you should read the errorobject that is returned. The most likely case is that theusername or email has already been taken by anotheruser. You should clearly communicate this to yourusers, and ask them try a dierent username.

    You are free to use an email address as the username.Simply ask your users to enter their email, but ll it inthe username property will work asnormal. We'll go over how this is handled in the resetpassword section.

    Logging In

    Of course, after you allow users to sign up, you need beable to let them log in to their account in the future. Todo this, you can use the class method .

    Verifying Emails

    Enabling email verication in an application's settingsallows the application to reserve part of its experience

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    for users with conrmed email addresses. Emailverication adds the key to the object. When a 's is set ormodied, is set to . Parse thenemails the user a link which will set to .

    There are three states to consider:

    Current User

    It would be bothersome if the user had to log in everytime they open your app. You can avoid this by usingthe cached object.

    Whenever you use any signup or login methods, theuser is cached on disk. You can treat this cache as asession, and automatically assume the user is logged in:

    You can clear the current user by logging them out:

    - the user conrmed his or her emailaddress by clicking on the link Parse emailedthem. can never have a valuewhen the user account is rst created.

    1

    - at the time the object was lastfetched, the user had not conrmed his or heremail address. If is , considercalling on the .

    2

    missing - the was created when emailverication was o or the does nothave an .

    3

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Anonymous Users

    Being able to associate data and objects with individualusers is highly valuable, but sometimes you want to beable to do this without forcing a user to specify ausername and password.

    An anonymous user is a user that can be createdwithout a username and password but still has all of thesame capabilities as any other . After loggingout, an anonymous user is abandoned, and its data is nolonger accessible.

    You can create an anonymous user using :

    You can convert an anonymous user into a regular userby setting the username and password, then calling , or by logging in or linking with a service likeFacebook or Twitter. The converted user will retain allof its data. To determine whether the current user is ananonymous user, you can check

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    :

    Anonymous users can also be automatically created foryou without requiring a network request, so that youcan begin working with your user immediately whenyour application starts. When you enable automaticanonymous user creation at application startup, will never be . Theuser will automatically be created in the cloud the rsttime the user or any object with a relation to the user issaved. Until that point, the user's object ID will be .Enabling automatic user creation makes associatingdata with your users painless. For example, in your method, you might write:

    Setting the Current User

    If youve created your own authentication routines, orotherwise logged in a user on the server side, you cannow pass the session token to the client and use the method. This method will ensure the sessiontoken is valid before setting the current user.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Security For User Objects

    The class is secured by default. Data storedin a can only be modied by that user. Bydefault, the data can still be read by any client. Thus,some objects are authenticated and can bemodied, whereas others are read-only.

    Specically, you are not able to invoke any of the or type methods unless the wasobtained using an authenticated method, like or . This ensures that only the user can alter theirown data.

    The following illustrates this security policy:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    The obtained from willalways be authenticated.

    If you need to check if a is authenticated,you can invoke the method. You donot need to check with objects that are obtained via an authenticated method.

    Security for Other Objects

    The same security model that applies to the can be applied to other objects. For any object, you canspecify which users are allowed to read the object, andwhich users are allowed to modify an object. Tosupport this type of security, each object has an accesscontrol list, implemented by the class.

    The simplest way to use a is to specify that anobject may only be read or written by a single user. Tocreate such an object, there must rst be a logged in . Then, generates a that limits access to that user. An object'sACL is updated when the object is saved, like any otherproperty. Thus, to create a private note that can only beaccessed by the current user:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    This note will then only be accessible to the currentuser, although it will be accessible to any device wherethat user is signed in. This functionality is useful forapplications where you want to enable access to userdata across multiple devices, like a personal todo list.

    Permissions can also be granted on a per-user basis.You can add permissions individually to a using and . For example,let's say you have a message that will be sent to a groupof several users, where each of them have the rights toread and delete that message:

    You can also grant permissions to all users at onceusing and .This allows patterns like posting comments on amessage board. For example, to create a post that canonly be edited by its author, but can be read by anyone:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    To help ensure that your users' data is secure bydefault, you can set a default ACL to be applied to allnewly-created :

    In the code above, the second parameter tosetDefaultACL tells Parse to ensure that the defaultACL assigned at the time of object creation allows readand write access to the current user at that time.Without this setting, you would need to reset thedefaultACL every time a user logs in or out so that thecurrent user would be granted access appropriately.With this setting, you can ignore changes to the currentuser until you explicitly need to grant dierent kinds ofaccess.

    Default ACLs make it easy to create apps that followcommon access patterns. An application like Twitter,for example, where user content is generally visible tothe world, might set a default ACL such as:

    For an application like Dropbox, where a user's data isonly accessible by the user itself unless explicitpermission is given, you would provide a default ACLwhere only the current user is given access:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    An application that logs data to Parse but doesn'tprovide any user access to that data would instead denyaccess to the current user while providing a restrictiveACL:

    Operations that are forbidden, such as deleting anobject that you do not have write access to, result in a error code. Forsecurity purposes, this prevents clients fromdistinguishing which object ids exist but are secured,versus which object ids do not exist at all.

    Resetting Passwords

    It's a fact that as soon as you introduce passwords intoa system, users will forget them. In such cases, ourlibrary provides a way to let them securely reset theirpassword.

    To kick o the password reset ow, ask the user fortheir email address, and call:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    This will attempt to match the given email with theuser's email or username eld, and will send them apassword reset email. By doing this, you can opt to haveusers use their email as their username, or you cancollect it separately and store it in the email eld.

    The ow for password reset is as follows:

    Note that the messaging in this ow will reference yourapp by the name that you specied when you createdthis app on Parse.

    Querying

    To query for users, you need to use the special userquery:

    User requests that their password be reset bytyping in their email.

    1

    Parse sends an email to their address, with aspecial password reset link.

    2

    User clicks on the reset link, and is directed to aspecial Parse page that will allow them type in anew password.

    3

    User types in a new password. Their passwordhas now been reset to a value they specify.

    4

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    In addition, you can use to get a by id.

    Associations

    Associations involving a work right of thebox. For example, let's say you're making a bloggingapp. To store a new post for a user and retrieve all theirposts:

    Facebook Users

    Parse provides an easy way to integrate Facebook withyour application. The Facebook SDK can be used withour SDK, and is integrated with the class tomake linking your users to their Facebook identitieseasy.

    Using our Facebook integration, you can associate anauthenticated Facebook user with a . Withjust a few lines of code, you'll be able to provide a "Login with Facebook" option in your app, and be able to

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    save their data to Parse.

    Note: Parse is compatible with both Facebook SDK 3.xand 4.x for Android. These instructions are forFacebook SDK 4.x.

    S E T U P

    To start using Facebook with Parse, you need to:

    Facebook's Android SDK provides an enhanced loginexperience on devices that have Facebook's ocialAndroid app installed. This allows users of apps thatsupport Facebook login to sign in directly through theFacebook app, using credentials that are already on thedevice. If the Facebook app is not installed, the defaultdialog-based authentication will be used. Facebook callsthis feature "Single sign-on" (SSO), and requires you tooverride in your calling :

    Set up a Facebook app, if you haven't already.1

    Add your application's Facebook Application IDon your Parse application's settings page.

    2

    Follow Facebook's instructions for gettingstarted with the Facebook SDK to create an applinked to the Facebook SDK. Once you get toStep 6, stop after linking the Facebook SDKproject and conguring the Facebook app ID. Youcan use our guide to attach your Parse users toFacebook accounts when logging in.

    3

    Add to your Gradle dependencies.This includes the contents of the and the repository, so be sure to remove as needed toprevent duplicate dependencies, otherwise a will be thrown.

    4

    Add the following where you initialize the ParseSDK in your :

    5

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    If your is already using ,you can avoid collisions by specifying yourown request code oset when initializing

    . Otherwise, a sensibledefault will be used.

    If you encounter any issues that are Facebook-related, agood resource is the ocial Facebook SDK forAndroid page.

    There are two main ways to use Facebook with yourParse users: (1) logging in as a Facebook user andcreating a , or (2) linking Facebook to anexisting .

    L O G I N & S I G N U P

    provides a way to allow yours to log in or sign up through Facebook. Thisis generally accomplished using the

    method:

    It is up to you to record any data that you need from theFacebook user after they authenticate. To accomplishthis, you'll need to do a graph query via Facebook's SDK.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    When this code is run, the following happens:

    In order to display the Facebook login dialogs andactivities, the current must be provided(often, the current activity is when calling from withinthe ) as we have done above.

    integration doesn't require any permissionsto work out of the box (i.e. is perfectlyacceptable). When logging in, you can only use read

    The user is shown the Facebook login dialog or aprompt generated by the Facebook app.

    1

    The user authenticates via Facebook, and yourapp receives a callback.

    2

    Our SDK receives the user's Facebook accessdata and saves it to a . If no exists with the same Facebook ID, then a new is created.

    3

    Your is called with the user.4

    The current user reference will be updated to thisuser.

    5

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    permissions. See our documentation below aboutrequesting additional permissions (read or publish).Read more about permissions on Facebook'sdeveloper guide.

    F A C E B O O K L I N K I N G

    If you want to associate an existing to aFacebook account, you can link it like so:

    The steps that happen when linking are very similar tolog in. The dierence is that on successful login, theexisting is updated with the Facebookinformation. Future logins via Facebook will now log theuser into their existing account.

    If you want to unlink Facebook from a user, simply dothis:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    R E Q U E S T I N G P E R M I S S I O N S

    As of v3.0 of the Facebook SDK, read and publishpermissions must be requested separately. To requestadditional permissions, you may call

    or

    . For more information about requesting newpermissions, please see Facebook's APIdocumentation for these functions.

    After successfully retrieving new permissions, pleasecall

    , which will save any changes to thesession token back to the and ensure thatthis session data follows the user wherever it logs in.

    F A C E B O O K S D K A N D P A R S E

    The Facebook Android SDK provides a number ofhelper classes for interacting with Facebook's API.Generally, you will use the class tointeract with Facebook on behalf of your logged-inuser. You can read more about the Facebook SDKhere.

    To access the user's you can simply call to access the instance, which can then be passed to

    s.

    Twitter Users

    As with Facebook, Parse also provides an easy way tointegrate Twitter authentication into your application.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    The Parse SDK provides a straightforward way toauthorize and link a Twitter account to yours. With just a few lines of code, you'll be ableto provide a "log in with Twitter" option in your app, andbe able to save their data to Parse.

    S E T U P

    To start using Twitter with Parse, you need to:

    If you encounter any issues that are Twitter-related, agood resource is the ocial Twitter documentation.

    There are two main ways to use Twitter with yourParse users: (1) logging in as a Twitter user and creatinga , or (2) linking Twitter to an existing .

    L O G I N & S I G N U P

    provides a way to allow your

    Set up a Twitter app, if you haven't already.1

    Add your application's Twitter consumer key onyour Parse application's settings page.

    2

    When asked to specify a "Callback URL" for yourTwitter app, please insert a valid URL. This valuewill not be used by your iOS or Androidapplication, but is necessary in order to enableauthentication through Twitter.

    3

    Add to your Gradle dependencies.This includes the contents of the and the repository, so be sure to remove as needed toprevent duplicate dependencies, otherwise a will be thrown.

    4

    Add the following where you initialize the ParseSDK in your

    5

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    s to log in or sign up through Twitter. This isaccomplished using the method:

    When this code is run, the following happens:

    In order to display the Twitter login dialogs andactivities, the current must be provided (often,the current context is when calling fromwithin the ) as we have done above.

    T W I T T E R L I N K I N G

    If you want to associate an existing with aTwitter account, you can link it like so:

    The user is shown the Twitter login dialog.1

    The user authenticates via Twitter, and your appreceives a callback.

    2

    Our SDK receives the Twitter data and saves it toa . If it's a new user based on theTwitter handle, then that user is created.

    3

    Your is called with the user.4

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    The steps that happen when linking are very similar tolog in. The dierence is that on successful login, theexisting is updated with the Twitterinformation. Future logins via Twitter will now log theuser into their existing account.

    If you want to unlink Twitter from a user, simply do this:

    T W I T T E R A P I C A L L S

    Our SDK provides a straightforward way to sign yourAPI HTTP requests to the Twitter REST API when yourapp has a Twitter-linked . To make a requestthrough our API, you can use the singletonprovided by :

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Was this section helpful? NOYES

    Want to contribute to this doc? Edit this section.

    SessionsSessions represent an instance of a user logged into adevice. Sessions are automatically created when userslog in or sign up. They are automatically deleted whenusers log out. There is one distinct objectfor each user-installation pair; if a user issues a loginrequest from a device they're already logged into, thatuser's previous object for that Installationis automatically deleted. objects arestored on Parse in the Session class, and you can viewthem on the Parse.com Data Browser. We provide a setof APIs to manage objects in your app.

    is a subclass of , so you can

    Session APIs are only available in apps with revocablesessions enabled. Parse apps created after March 25,2015 have this enabled by default ("Require RevocableSessions" toggle in your Parse.com app settings page). Ifyou have an existing app, you can upgrade to revocablesessions by following the Session Migration Tutorial.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    query, update, and delete sessions in the same way thatyou manipulate normal objects on Parse. Because theParse Cloud automatically creates sessions when youlog in or sign up users, you should not manually create objects unless you are building a "Parsefor IoT" app (e.g. Arduino or Embedded C). Deleting a will log the user out of the device that iscurrently using this session's token.

    Unlike other Parse objects, the class doesnot have Cloud Code triggers. So you cannot register a or handler for the Session class.

    Properties

    The object has these special elds:

    (readonly): String token forauthentication on Parse API requests. In theresponse of queries, only yourcurrent object will contain a sessiontoken.

    : (readonly) Pointer to the objectthat this session is for.

    (readonly): Information about howthis session was created (e.g. ).

    could have values: , , , or . The action iswhen the developer manually creates thesession by saving a object.The action is when the user isupgraded to revocable session from alegacy session token.

    could have values: , , , or .

    (readonly): Boolean for whether thissession is restricted.

    Restricted sessions do not have write

    permissions on , ,

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Handling Invalid Session Token Error

    Apps created before March 25, 2015 use legacy sessiontokens until you migrate them to use the new revocablesessions. On API requests with legacy tokens, if thetoken is invalid (e.g. User object was deleted), then therequest is executed as a non-logged in user and noerror was returned. On API requests with revocablesession tokens, an invalid session token will always failwith the "invalid session token" error. This newbehavior lets you know when you need to ask the userto log in again.

    With revocable sessions, your current session tokencould become invalid if its corresponding object is deleted from the Parse Cloud. This could

    permissions on , ,and classes on Parse. Restrictedsessions also cannot read unrestrictedsessions.

    All sessions that the Parse Cloudautomatically creates during userlogin/signup will be unrestricted. Allsessions that the developer manuallycreates by saving a new object from the client (only needed for"Parse for IoT" apps) will be restricted.

    (readonly): Approximate UTC datewhen this object will beautomatically deleted. You can congure sessionexpiration settings (either 1-year inactivityexpiration or no expiration) in your app'sParse.com dashboard settings page.

    (can be set only once): Stringreferring to the where thesession is logged in from. For Parse SDKs, thiseld will be automatically set when users log in orsign up. All special elds except can only be set automatically by the Parse Cloud.You can add custom elds onto objects, but please keep in mind that any logged-in device (with session token) can read othersessions that belong to the same user (unless youdisable Class-Level Permissions, see below).

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    happen if you implement a Session Manager UI that letsusers log out of other devices, or if you manually deletethe session via Cloud Code, REST API, or Data Browser.Sessions could also be deleted due to automaticexpiration (if congured in app settings). When adevice's session token no longer corresponds to a object on the Parse Cloud, all APIrequests from that device will fail with Error 209:invalid session token.

    To handle this error, we recommend writing a globalutility function that is called by all of your Parse requesterror callbacks. You can then handle the "invalid sessiontoken" error in this global function. You should promptthe user to login again so that they can obtain a newsession token. This code could look like this:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Security

    objects can only be accessed by the userspecied in the user eld. All objects havean ACL that is read and write by that user only. Youcannot change this ACL. This means querying forsessions will only return objects that match the currentlogged-in user.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    When you log in a user via , Parse will automaticallycreate a new unrestricted object in theParse Cloud. Same for signups and Facebook/Twitterlogins.

    Session objects manually created from client SDKs (bycreating an instance of , and saving it) arealways restricted. You cannot manually create anunrestricted sessions using the object creation API.

    Restricted sessions are prohibited from creating,modifying, or deleting any data in the , , and classes. Restrictedsession also cannot read unrestricted sessions.Restricted Sessions are useful for "Parse for IoT"devices (e.g Arduino or Embedded C) that may run in aless-trusted physical environment than mobile apps.However, please keep in mind that restricted sessionscan still read data on , , and classes, and can read/write data in any otherclass just like a normal session. So it is still importantfor IoT devices to be in a safe physical environment andideally use encrypted storage to store the sessiontoken.

    If you want to prevent restricted Sessions frommodifying classes other than , ,or , you can write a Cloud Code handler for that class:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Was this section helpful? NOYES

    You can congure Class-Level Permissions (CLPs) forthe Session class just like other classes on Parse. CLPsrestrict reading/writing of sessions via the API, but do not restrict Parse Cloud'sautomatic session creation/deletion when users log in,sign up, and log out. We recommend that you disable allCLPs not needed by your app. Here are some commonuse cases for Session CLPs:

    Want to contribute to this doc? Edit this section.

    RolesAs your app grows in scope and user-base, you may ndyourself needing more coarse-grained control overaccess to pieces of your data than user-linked ACLs canprovide. To address this requirement, Parse supports aform of Role-based Access Control. Roles provide alogical way of grouping users with common accessprivileges to your Parse data. Roles are named objects

    Find, Delete Useful for building a UI screenthat allows users to see their active session on alldevices, and log out of sessions on other devices.If your app does not have this feature, you shoulddisable these permissions.

    Create Useful for "Parse for IoT" apps (e.g.Arduino or Embedded C) that provision restricteduser sessions for other devices from the phoneapp. You should disable this permission whenbuilding apps for mobile and web. For "Parse forIoT" apps, you should check whether your IoTdevice actually needs to access user-specicdata. If not, then your IoT device does not need auser session, and you should disable thispermission.

    Get, Update, Add Field Unless you need theseoperations, you should disable these permissions.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    that contain users and other roles. Any permissiongranted to a role is implicitly granted to its users as wellas to the users of any roles that it contains.

    For example, in your application with curated content,you may have a number of users that are considered"Moderators" and can modify and delete contentcreated by other users. You may also have a set of usersthat are "Administrators" and are allowed all of thesame privileges as Moderators, but can also modify theglobal settings for the application. By adding users tothese roles, you can ensure that new users can be mademoderators or administrators, without having tomanually grant permission to every resource for eachuser.

    We provide a specialized class called thatrepresents these role objects in your client code. is a subclass of , and has all ofthe same features, such as a exible schema, automaticpersistence, and a key value interface. All the methodsthat are on also exist on . Thedierence is that has some additions specicto management of roles.

    Properties

    has several properties that set it apart from :

    Security for Role Objects

    name: The name for the role. This value isrequired, and can only be set once as a role isbeing created. The name must consist ofalphanumeric characters, spaces, -, or _. Thisname will be used to identify the Role withoutneeding its objectId.

    users: A relation to the set of users that willinherit permissions granted to the containingrole.

    roles: A relation to the set of roles whose usersand roles will inherit permissions granted to thecontaining role.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Security for Role Objects

    The uses the same security scheme (ACLs)as all other objects on Parse, except that it requires anACL to be set explicitly. Generally, only users withgreatly elevated privileges (e.g. a master user orAdministrator) should be able to create or modify aRole, so you should dene its ACLs accordingly.Remember, if you give write-access to a to auser, that user can add other users to the role, or evendelete the role altogether.

    To create a new , you would write:

    You can add users and roles that should inherit yournew role's permissions through the "users" and "roles"relations on :

    Take great care when assigning ACLs to your roles sothat they can only be modied by those who shouldhave permissions to modify them.

    Security for Other Objects

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Security for Other Objects

    Now that you have created a set of roles for use in yourapplication, you can use them with ACLs to dene theprivileges that their users will receive. Each can specify a , which provides an accesscontrol list that indicates which users and roles shouldbe granted read or write access to the object.

    Giving a role read or write permission to an object isstraightforward. You can either use the :

    You can avoid querying for a role by specifying its namefor the ACL:

    Role-based s can also be used whenspecifying default ACLs for your application, making iteasy to protect your users' data while granting accessto users with additional privileges. For example, amoderated forum application might specify a defaultACL like this:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Role Hierarchy

    As described above, one role can contain another,establishing a parent-child relationship between thetwo roles. The consequence of this relationship is thatany permission granted to the parent role is implicitlygranted to all of its child roles.

    These types of relationships are commonly found inapplications with user-managed content, such asforums. Some small subset of users are"Administrators", with the highest level of access totweaking the application's settings, creating newforums, setting global messages, and so on. Another setof users are "Moderators", who are responsible forensuring that the content created by users remainsappropriate. Any user with Administrator privilegesshould also be granted the permissions of anyModerator. To establish this relationship, you wouldmake your "Administrators" role a child role of"Moderators", like this:

    Want to contribute to this doc? Edit this section.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Was this section helpful? NOYES

    FilesThe ParseFile

    lets you store application les in the cloudthat would otherwise be too large or cumbersome to tinto a regular . The most common use caseis storing images but you can also use it for documents,videos, music, and any other binary data (up to 10megabytes).

    Getting started with is easy. First, you'll needto have the data in form and then create a with it. In this example, we'll just use a string:

    Notice in this example that we give the le a name of . There's two things to note here:

    Next you'll want to save the le up to the cloud. As with , there are many variants of the method you can use depending on what sort of callback

    You don't need to worry about lenamecollisions. Each upload gets a unique identier sothere's no problem with uploading multiple lesnamed .

    It's important that you give a name to the le thathas a le extension. This lets Parse gure out thele type and handle it accordingly. So, if you'restoring PNG images, make sure your lenameends with .

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    and error handling suits you.

    Finally, after the save completes, you can associate a onto a just like any other pieceof data:

    Retrieving it back involves calling one of the variants on the . Here we retrieve theresume le o another JobApplication object:

    Just like on , you will most likely want touse the background version of .

    Progress

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Was this section helpful? NOYES

    Progress

    It's easy to get the progress of both uploads anddownloads using ParseFile by passing aProgressCallback to and . For example:

    You can delete les that are referenced by objectsusing the REST API. You will need to provide themaster key in order to be allowed to delete a le.

    If your les are not referenced by any object in yourapp, it is not possible to delete them through the RESTAPI. You may request a cleanup of unused les in yourapp's Settings page. Keep in mind that doing so maybreak functionality which depended on accessingunreferenced les through their URL property. Filesthat are currently associated with an object will not beaected.

    Want to contribute to this doc? Edit this section.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    GeoPointsParse allows you to associate real-world latitude andlongitude coordinates with an object. Adding a to a allows queries to takeinto account the proximity of an object to a referencepoint. This allows you to easily do things like nd outwhat user is closest to another user or which places areclosest to a user.

    ParseGeoPoint

    To associate a point with an object you rst need tocreate a . For example, to create a pointwith latitude of 40.0 degrees and -30.0 degreeslongitude:

    This point is then stored in the object as a regular eld.

    Geo Queries

    Now that you have a bunch of objects with spatialcoordinates, it would be nice to nd out which objectsare closest to a point. This can be done by addinganother restriction to using .Getting a list of ten places that are closest to a usermay look something like:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    At this point will be an array of objectsordered by distance (nearest to farthest) from . Note that if an additional/ constraint isapplied, it will take precedence over the distanceordering.

    To limit the results using distance, check out , , and .

    It's also possible to query for the set of objects that arecontained within a particular area. To nd the objects ina rectangular bounding box, add the restriction to your .

    Caveats

    At the moment there are a couple of things to watchout for:

    Each ParseObject class may only have one keywith a ParseGeoPoint object.

    1

    Using the constraint will also limit

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Was this section helpful? NOYES

    Want to contribute to this doc? Edit this section.

    RelationsThere are three kinds of relationships. One-to-onerelationships enable one object to be associated withanother object. One-to-many relationships enable oneobject to have many related objects. Finally, many-to-many relationships enable complex relationships amongmany objects.

    There are four ways to build relationships in Parse:

    One-to-Many

    When youre thinking about one-to-many relationshipsand whether to implement Pointers or Arrays, there areseveral factors to consider. First, how many objects areinvolved in this relationship? If the "many" side of therelationship could contain a very large number (greaterthan 100 or so) of objects, then you have to usePointers. If the number of objects is small (fewer than100 or so), then Arrays may be more convenient,especially if you typically need to get all of the relatedobjects (the "many" in the "one-to-many relationship")at the same time as the parent object.

    U S I N G P O I N T E R S

    Let's say we have a game app. The game keeps track of

    Using the constraint will also limitresults to within 100 miles.

    2

    Points should not equal or exceed the extremeends of the ranges. Latitude should not be -90.0or 90.0. Longitude should not be -180.0 or180.0. Attempting to set latitude or longitude outof bounds will cause an error.

    3

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    the player's score and achievements every time shechooses to play. In Parse, we can store this data in asingle object. If the game becomes incrediblysuccessful, each player will store thousands of

    objects in the system. For circumstances like this,where the number of relationships can be arbitrarilylarge, Pointers are the best option.

    Suppose in this game app, we want to make sure thatevery object is associated with a Parse User. Wecan implement this like so:

    We can obtain all of the objects created by aParse User with a query:

    And, if we want to nd the Parse User who created aspecic , that is a lookup on the key:

    For most scenarios, Pointers will be your best bet forimplementing one-to-many relationships.

    U S I N G A R R A Y S

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Arrays are ideal when we know that the number ofobjects involved in our one-to-many relationship aregoing to be small. Arrays will also provide someproductivity benet via the parameter.Supplying the parameter will enable you to obtain all ofthe "many" objects in the "one-to-many" relationship atthe same time that you obtain the "one" object.However, the response time will be slower if thenumber of objects involved in the relationship turns outto be large.

    Suppose in our game, we enabled players to keep trackof all the weapons their character has accumulated asthey play, and there can only be a dozen or so weapons.In this example, we know that the number of weaponsis not going to be very large. We also want to enablethe player to specify the order in which the weaponswill appear on screen. Arrays are ideal here because thesize of the array is going to be small and because wealso want to preserve the order the user has set eachtime they play the game:

    Let's start by creating a column on our Parse Userobject called .

    Now let's store some objects in the :

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Later, if we want to retrieve the objects, it's justone line of code:

    Sometimes, we will want to fetch the "many" objects inour one-to-many relationship at the same time as wefetch the "one" object. One trick we could employ is touse the (or in Android) parameterwhenever we use a Parse Query to also fetch the arrayof objects (stored in the column)along with the Parse User object:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    You can also get the "one" side of the one-to-manyrelationship from the "many" side. For example, if wewant to nd all Parse User objects who also have agiven , we can write a constraint for our querylike this:

    Many-to-Many

    Now lets tackle many-to-many relationships. Supposewe had a book reading app and we wanted to model objects and objects. As we know, a givenauthor can write many books, and a given book canhave multiple authors. This is a many-to-manyrelationship scenario where you have to choosebetween Arrays, Parse Relations, or creating your ownJoin Table.

    The decision point here is whether you want to attachany metadata to the relationship between two entities.If you dont, Parse Relation or using Arrays are going tobe the easiest alternatives. In general, using arrays willlead to higher performance and require fewer queries.If either side of the many-to-many relationship couldlead to an array with more than 100 or so objects, then,for the same reason Pointers were better for one-to-many relationships, Parse Relation or Join Tables will bebetter alternatives.

    On the other hand, if you want to attach metadata to

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    the relationship, then create a separate table (the "JoinTable") to house both ends of the relationship.Remember, this is information about the relationship,not about the objects on either side of the relationship.Some examples of metadata you may be interested in,which would necessitate a Join Table approach, include:

    U S I N G P A R S E R E L A T I O N S

    Using Parse Relations, we can create a relationshipbetween a and a few objects. In the DataBrowser, you can create a column on the object oftype relation and name it .

    After that, we can associate a few authors with thisbook:

    To get the list of authors who wrote a book, create aquery:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Perhaps you even want to get a list of all the books towhich an author contributed. You can create a slightlydierent kind of query to get the inverse of therelationship:

    U S I N G J O I N T A B L E S

    There may be certain cases where we want to knowmore about a relationship. For example, suppose wewere modeling a following/follower relationshipbetween users: a given user can follow another user,much as they would in popular social networks. In ourapp, we not only want to know if User A is followingUser B, but we also want to know when User A started

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    following User B. This information could not becontained in a Parse Relation. In order to keep track ofthis data, you must create a separate table in which therelationship is tracked. This table, which we will call , would have a column and a column,each with a pointer to a Parse User. Alongside therelationship, you can also add a column with a object named .

    Now, when you want to save the following relationshipbetween two users, create a row in the table,lling in the , , and keys appropriately:

    If we want to nd all of the people we are following, wecan execute a query on the table:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Its also pretty easy to nd all the users that arefollowing the current user by querying on the key:

    U S I N G A N A R R A Y

    Arrays are used in Many-to-Many relationships in muchthe same way that they are for One-to-Manyrelationships. All objects on one side of the relationshipwill have an Array column containing several objects onthe other side of the relationship.

    Suppose we have a book reading app with and objects. The object will contain an Arrayof objects (with a key named ). Arraysare a great t for this scenario because it's highlyunlikely that a book will have more than 100 or soauthors. We will put the Array in the object forthis reason. After all, an author could write more than100 books.

    Here is how we save a relationship between a andan .

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Because the author list is an Array, you should use the (or on Android) parameter whenfetching a so that Parse returns all the authorswhen it also returns the book:

    At that point, getting all the objects in a given is a pretty straightforward call:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Finally, suppose you have an and you want tond all the objects in which she appears. This isalso a pretty straightforward query with an associatedconstraint:

    One-to-One

    In Parse, a one-to-one relationship is great forsituations where you need to split one object into twoobjects. These situations should be rare, but twoexamples include:

    Limiting visibility of some user data. In thisscenario, you would split the object in two, whereone portion of the object contains data that isvisible to other users, while the related objectcontains data that is private to the original user(and protected via ACLs).

    Splitting up an object for size. In this scenario,your original object is greater than the 128K

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Was this section helpful? NOYES

    Was this section helpful? NOYES

    Thank you for reading this far. We apologize for thecomplexity. Modeling relationships in data is a hardsubject, in general. But look on the bright side: it's stilleasier than relationships with people.

    Want to contribute to this doc? Edit this section.

    Handling ErrorsMany of the methods on , including , , and will throw a on aninvalid request, such as deleting or editing an objectthat no longer exists in the cloud, or when there is anetwork failure preventing communication with theParse Cloud. You will need to catch and deal with theseexceptions.

    For more details, look at the Android API.

    Want to contribute to this doc? Edit this section.

    DataValid Data Types

    maximum size permitted for an object, so youdecide to create a secondary object to houseextra data. It is usually better to design your datamodel to avoid objects this large, rather thansplitting them up. If you can't avoid doing so, youcan also consider storing large data in a ParseFile.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    We've designed the Parse SDKs so that you typicallydon't need to worry about how data is saved whileusing the client SDKs. Simply add data to the , and it'll be saved correctly.

    Nevertheless, there are some cases where it's useful tobe aware of how data is stored on the Parse platform.

    Internally, Parse stores data as JSON, so any datatypethat can be converted to JSON can be stored on Parse.The framework can also handle and types.Overall, the following types are allowed for each eld inyour object:

    The type simply denotes that each value can becomposed of nested objects that are JSON-encodable.Keys including the characters or , along with thekey key, are reserved for the framework tohandle additional types, so don't use those yourself.

    We do not recommend storing large pieces of binarydata like images or documents in a .s should not exceed 128 kilobytes in size.We recommend you use s to store images,documents, and other types of les. You can do so byinstantiating a object and setting it on a eld.

    Data Type Lock-in

    String

    Number

    Boolean

    Array

    Object

    Date

    Null

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Data Type Lock-in

    When a class is initially created, it doesn't have aninherent schema dened. This means that for the rstobject, it could have any types of elds you want.

    However, after a eld has been set at least once, thateld is locked into the particular type that was saved.For example, if a object is saved with eld of type , that eld will be restricted to the type only (our SDK will return an error if you tryto save anything else).

    One special case is that any eld can be set to , nomatter what type it is.

    The Data Browser

    The Data Browser is the web UI where you can updateand create objects in each of your apps. Here, you cansee the raw JSON values that are saved that representseach object in your class.

    When using the interface, keep in mind the following:

    The Data Browser is also a great place to test the CloudCode validations contained in your Cloud Codefunctions (such as ). These are runwhenever a value is changed or object is deleted fromthe Data Browser, just as they would be if the value waschanged or deleted from your client code.

    Importing Data

    The , , elds cannotbe edited (these are set automatically).

    The value "(empty)" denotes that the eld hasnot been set for that particular object (this isdierent than ).

    You can remove a eld's value by hitting yourDelete key while the value is selected.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    You may import data into your Parse app by using CSVor JSON les. To create a new class with data from aCSV or JSON le, go to the Data Browser and click the"Import" button on the left hand column.

    The JSON format is an array of objects in our RESTformat or a JSON object with a that containsan array of objects. It must adhere to the JSONstandard. A le containing regular objects could looklike:

    Objects in either format should contain keys and valuesthat also satisfy the following:

    Normally, when objects are saved to Parse, they areautomatically assigned a unique identier through the eld, as well as a eld and eld which represent the time that theobject was created and last modied in the ParseCloud. These elds can be manually set when data isimported from a JSON le. Please keep in mind thefollowing:

    Key names must contain only numbers, letters,and underscore, and must start with a letter.

    No value may contain a hard newline ' '.

    Use a unique 10 character alphanumeric string asthe value of your elds.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    In addition to the exposed elds, objects in the ParseUser class can also have the eld set.The value of this eld is a that is the bcrypthashed password + salt in the modular crypt formatdescribed in this StackOverow answer. MostOpenSSL based bcrypt implementations should havebuilt-in methods to produce these strings.

    A le containing a object could look like:

    Note that in CSV the import eld types are limited to , , and .

    Exporting your Data

    You can request an export of your data at any timefrom your app's Settings page. The data export runs ata lower priority than production queries, so if your appis still serving queries, production trac will always begiven a higher priority, which may slow down thedelivery of your data export.

    E X P O R T F O R M A T S

    Use a UTC timestamp in the ISO 8601 formatwhen setting a value for the eld orthe eld.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Each collection will be exported in the same JSONformat used by our REST API and delivered in a singlezipped le. Since data is stored internally as JSON, thisallows us to ensure that the export closely matcheshow the data is saved to Parse. Other formats such asCSV cannot represent all of the data types supportedby Parse without losing information. If you'd like towork with your data in CSV format, you can use any ofthe JSON-to-CSV converters available widely on theweb.

    O F F L I N E A N A L Y S I S

    For oine analysis of your data, we highly recommendusing alternate ways to access your data that do notrequire extracting the entire collection at once. Forexample, you can try exporting only the data that haschanged since your last export. Here are some ways ofachieving this:

    Use the JavaScript SDK in a node app. will allow you to extractevery single object that matches a query. You canuse date constraints to make sure the query onlymatches data that has been updated since youlast ran this app. Your node app can write thisdata to disk for oine analysis.

    Use the REST API in a script. You can run queriesagainst your class and use skip/limit to pagethrough results, which can then be written to diskfor oine analysis. You can again use dateconstraints to make sure only newly updated datais extracted.

    If the above two options do not t your needs,you can try using the Data Browser to exportdata selectively. Use the Funnel icon to create alter for the specic data that you need toexport, such as newly updated objects. Once thelter has been applied, click on the Export dataicon on the upper right of your Data Browser.This type of export will only include the objects

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Was this section helpful? NOYES

    Want to contribute to this doc? Edit this section.

    SecurityAs your app development progresses, you will want touse Parse's security features in order to safeguard data.This document explains the ways in which you cansecure your apps.

    If your app is compromised, it's not only you as thedeveloper who suers, but potentially the users of yourapp as well. Continue reading for our suggestions forsensible defaults and precautions to take beforereleasing your app into the wild.

    Client vs. Server

    When an app rst connects to Parse, it identies itselfwith an Application ID and a Client key (or REST Key, or.NET Key, or JavaScript Key, depending on whichplatform you're using). These are not secret and bythemselves they do not secure an app. These keys areshipped as a part of your app, and anyone candecompile your app or proxy network trac from theirdevice to nd your client key. This exploit is even easierwith JavaScript one can simply "view source" in thebrowser and immediately nd your client key.

    This is why Parse has many other security features tohelp you secure your data. The client key is given out toyour users, so anything that can be done with just theclient key is doable by the general public, evenmalicious hackers.

    The master key, on the other hand, is denitely a

    that match your criteria.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    security mechanism. Using the master key allows you tobypass all of your app's security mechanisms, such asclass-level permissions and ACLs. Having the masterkey is like having root access to your app's servers, andyou should guard your master key with the same zealwith which you would guard your production machines'root password.

    The overall philosophy is to limit the power of yourclients (using client keys), and to perform any sensitiveactions requiring the master key in Cloud Code. You'lllearn how to best wield this power in the section titledImplementing Business Logic in Cloud Code.

    A nal note: All connections are made with HTTPS andSSL, and Parse will reject all non-HTTPS connections.As a result, you don't need to worry about man-in-the-middle attacks.

    Class-Level Permissions

    The second level of security is at the schema and datalevel. Enforcing security measures at this level willrestrict how and when client applications can accessand create data on Parse. When you rst begindeveloping your Parse application, all of the defaults areset so that you can be a more productive developer. Forexample:

    You can congure any of these permissions to apply toeveryone, no one, or to specic users or roles in yourapp. Roles are groups that contain users or other roles,which you can assign to an object to restrict its use. Anypermission granted to a role is also granted to any of itschildren, whether they are users or other roles, enabling

    A client application can create new classes onParse

    A client application can add elds to classes

    A client application can modify or query forobjects on Parse

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    you to create an access hierarchy for your apps. Each ofthe Parse guides includes a detailed description ofemploying Roles in your apps.

    Once you are condent that you have the right classesand relationships between classes in your app, youshould begin to lock it down by doing the following:

    Almost every class that you create should have thesepermissions tweaked to some degree. For classeswhere every object has the same permissions, class-level settings will be most eective. For example, onecommon use case entails having a class of static datathat can be read by anyone but written by no one.

    R E S T R I C T I N G C L A S S C R E A T I O N

    As a start, you can congure your application so thatclients cannot create new classes on Parse. This is donefrom the Settings tab on the Data Browser. Scroll downto the App Permissions section and turn o Allowclient class creation. Once enabled, classes may onlybe created from the Data Browser. This will preventattackers from lling your database with unlimited,arbitrary new classes.

    C O N F I G U R I N G C L A S S - L E V E L P E R M I S S I O N S

    Parse lets you specify what operations are allowed perclass. This lets you restrict the ways in which clients canaccess or modify your classes. To change thesesettings, go to the Data Browser, select a class, andclick the "Security" button.

    You can congure the client's ability to perform each ofthe following operations for the selected class:

    Read:

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    For each of the above actions, you can grant permissionto all users (which is the default), or lock permissions

    Get: With Get permission, users can fetchobjects in this table if they know theirobjectIds.

    Find: Anyone with Find permission canquery all of the objects in the table, even ifthey dont know their objectIds. Any tablewith public Find permission will becompletely readable by the public, unlessyou put an ACL on each object.

    Write:

    Update: Anyone with Update permissioncan modify the elds of any object in thetable that doesn't have an ACL. For publiclyreadable data, such as game levels orassets, you should disable this permission.

    Create: Like Update, anyone with Createpermission can create new objects of aclass. As with the Update permission, you'llprobably want to turn this o for publiclyreadable data.

    Delete: With this permission, people candelete any object in the table that doesn'thave an ACL. All they need is its objectId.

    Add elds: Parse classes have schemas that areinferred when objects are created. While you'redeveloping your app, this is great, because youcan add a new eld to your object without havingto make any changes on the backend. But onceyou ship your app, it's very rare to need to addnew elds to your classes automatically. Youshould pretty much always turn o thispermission for all of your classes when yousubmit your app to the public.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    down to a list of roles and users. For example, a classthat should be available to all users would be set toread-only by only enabling get and nd. A logging classcould be set to write-only by only allowing creates. Youcould enable moderation of user-generated content byproviding update and delete access to a particular setof users or roles.

    Object-Level Access Control

    Once you've locked down your schema and class-levelpermissions, it's time to think about how data isaccessed by your users. Object-level access controlenables one user's data to be kept separate fromanother's, because sometimes dierent objects in aclass need to be accessible by dierent people. Forexample, a users private personal data should beaccessible only to them.

    Parse also supports the notion of anonymous users forthose apps that want to store and protect user-specicdata without requiring explicit login.

    When a user logs into an app, they initiate a sessionwith Parse. Through this session they can add andmodify their own data but are prevented frommodifying other users' data.

    A C C E S S C O N T R O L L I S T S

    The easiest way to control who can access which datais through access control lists, commonly known asACLs. The idea behind an ACL is that each object has alist of users and roles along with what permissions thatuser or role has. A user needs read permissions (ormust belong to a role that has read permissions) inorder to retrieve an object's data, and a user needswrite permissions (or must belong to a role that haswrite permissions) in order to update or delete thatobject.

    Once you have a User, you can start using ACLs.Remember: Users can be created through traditional

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    username/password signup, through a third-party loginsystem like Facebook or Twitter, or even by usingParse's automatic anonymous users functionality. Toset an ACL on the current user's data to not be publiclyreadable, all you have to do is:

    Most apps should do this. If you store any sensitive userdata, such as email addresses or phone numbers, youneed to set an ACL like this so that the user's privateinformation isn't visible to other users. If an objectdoesn't have an ACL, it's readable and writeable byeveryone. The only exception is the class. Wenever allow users to write each other's data, but theycan read it by default. (If you as the developer need toupdate other objects, remember that yourmaster key can provide the power to do this.)

    To make it super easy to create user-private ACLs forevery object, we have a way to set a default ACL thatwill be used for every new object you create:

    If you want the user to have some data that is publicand some that is private, it's best to have two separateobjects. You can add a pointer to the private data fromthe public one.

  • $QGURLG'HYHORSHUV*XLGH_3DUVH

    KWWSVSDUVHFRPGRFVDQGURLGJXLGHFRQILJ

    Of course, you can set dierent read and writepermissions on an object. For example, this is how youwould create an ACL for a public post by a user, whereanyone can read it:

    Sometimes it's inconvenient to manage permissions ona per-user basis, and you want to have groups of userswho get treated the same (like a set of admins withspecial powers). Roles are are a special kind of objectthat let you create a group of users that can all beassigned to the ACL. The best thing about roles is thatyou can add and remove users from a role withouthaving to update every single object that is restricted tothat role. To create an object that is writeable only byadmins:

    Of course, this snippet assumes you've already createda role named "admins". This is often reasonable whenyou have a small set of special roles set up whiledeveloping your app. Roles can also be created andupdated on the y for example, adding new friendsto a "friendOf_" role after each connection is


Recommended