凉鞋学 Parse Android Guide(七) 面向 Android 的Parse 云服务(终)

来源:互联网 发布:软件开发怎么学 编辑:程序博客网 时间:2024/04/27 17:03

Subclasses(子类)

Parse is designed to get you up and running as quickly as possible. You can access all of your data using the ParseObject class and access any field with get(). In mature codebases, subclasses have many advantages, including terseness, extensibility, and support for autocomplete. Subclassing is completely optional, but can transform this code:

(Parse是为了让你尽可能地快速启动。你可以访问所有数据使用ParseObject类和访问任何字段用get()。在成熟的代码库里,子类有许多优势,包括简洁、可扩展性,支持自动完成。子类化是完全可选的,但是可以将这段代码:)

ParseObject shield =newParseObject("Armor");

shield.put("displayName","Wooden Shield");

shield.put("fireproof",false);

shield.put("rupees",50);

Into this:(转换成:)

Armor shield =newArmor();

shield.setDisplayName("Wooden Shield");

shield.setFireproof(false);

shield.setRupees(50);

Subclassing ParseObject(ParseObject子类化)

To create a ParseObject subclass:(创建一个ParseObject子类:)

1 Declare a subclass which extends ParseObject

声明一个子类继承ParseObject类

2 Add a @ParseClassName annotation. Its value should be the string you would pass into the ParseObject constructor, and makes all future class name references unnecessary.

   2 添加一个@ParseClassName注释。它的重要性应该是字符串你将通过ParseObject构造函数,使未来所有的类名不必要地引用它。

3 Ensure that your subclass has a public default (i.e. zero-argument) constructor. You must not modify any ParseObject fields in this constructor.

   3 确保你有一个公共的默认子类构造函数(即零参数)。你不能修改任何ParseObject字段在这个构造函数里。

4 Call ParseObject.registerSubclass(YourClass.class) in your Application constructor before calling Parse.initialize().

4 在你的应用程序的构造函数之前调用解析初始化()叫ParseObject.registerSubclass(YourClass.class)。

The following code sucessfully implements and registers the Armor subclass of ParseObject:// Armor.java(下面的代码成功地实现和寄存器的Armor ParseObject的子类:)

importcom.parse.ParseObject;

importcom.parse.ParseClassName;

 

@ParseClassName("Armor")

publicclassArmorextendsParseObject {

}

 

// App.java

importcom.parse.Parse;

importandroid.app.Application;

 

publicclassAppextendsApplication {

  @Override

  publicvoidonCreate() {

    super.onCreate();

 

    ParseObject.registerSubclass(Armor.class);

    Parse.initialize(this, PARSE_APPLICATION_ID, PARSE_CLIENT_KEY);

  }

}

Accessors, Mutators, and Methods(访问函数和方法)

Adding methods to your ParseObject subclass helps encapsulate logic about the class. You can keep all your logic about a subject in one place rather than using separate classes for business logic and storage/transmission logic.

You can add accessors and mutators for the fields of your ParseObject easily. Declare the getter and setter for the field as you normally would, but implement them in terms of get() and put(). The following example creates a displayName field in the Armor class:

(添加方法到你的ParseObject子类帮助封装逻辑的类。你可以保留你的所有逻辑主题在一个地方而不是使用独立类业务逻辑和存储器/传输逻辑。

您可以添加访问器和调整器为了你的ParseObject在这个领域容易。宣布getter和setter的字段如往常一样,但实现从get()和put()。下面的示例创建一个displayName字段装甲类:)

// Armor.java

@ParseClassName("Armor")

publicclassArmorextendsParseObject {

  publicString getDisplayName() {

    returngetString("displayName");

  }

  publicvoidsetDisplayName(String value) {

    put("displayName", value);

  }

}

You can now access the displayName field using armor.getDisplayName() and assign to it using armor.setDisplayName("Wooden Sword"). This allows your IDE to provide autocompletion as you develop your app and allows typos to be caught at compile-time.

Accessors and mutators of various types can be easily defined in this manner using the various forms of get() such as getInt(),getParseFile(), or getMap().

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

(你现在可以访问displayName字段使用armor.getDisplayName()和分配给它使用armor.setDisplayName("Wooden Sword")。 这允许你的IDE提供自动完成在你开发你的应用程序,并允许输入错误在编译时被抓住。

各种类型的访问器和调整器可以很容易地以这种方式定义使用各种形式的get()如getInt(),getParseFile(),或者getMap()。

如果你需要更复杂的逻辑超过简单的字段访问,您可以声明自己的方法:

)

publicvoidtakeDamage(intamount) {

  // Decrease the armor's durability and determine whether it has broken

  increment("durability", -amount);

  if(getDurability() <0) {

    setBroken(true);

  }

}

Initializing Subclasses(初始化子类)

You should create new instances of your subclasses using the constructors you have defined. Your subclass must define a public default constructor that does not modify fields of the ParseObject, which will be used throughout the Parse SDK to create strongly-typed instances of your subclass.

(你应该创建新的实例使用已经定义了构造函数的子类。你的子类必须定义一个公共的默认构造函数,不修改的字段ParseObject,这将被用来在整个解析SDK创建强类型的子类的实例。)

To create a reference to an existing object, use ParseObject.createWithoutData():

(创建一个引用现有对象,使用ParseObject.createWithoutData():)

Armor armorReference = ParseObject.createWithoutData(Armor.class, armor.getObjectId());

Queries(查询)

You can get a query for objects of a particular subclass using the static method ParseObject.getQuery(). The following example queries for armors that the user can afford:

(你可以得到一个查询对象的特定子类使用静态方法ParseObject.getQuery()。下面的示例查询,用户可以提供armors:)

ParseQuery<Armor> query = ParseObject.getQuery(Armor.class);

query.whereLessThanOrEqualTo("rupees", ParseUser.getCurrentUser().get("rupees"));

query.findInBackground(newFindCallback<Armor>() {

  @Override

  publicvoiddone(List<Armor> results, ParseException e) {

    for(Armor a : results) {

      // ...

    }

  }

});

Files(文件)

The ParseFile(解析文件)

ParseFile lets you store application files in the cloud that would otherwise be too large or cumbersome to fit into a regular ParseObject. The most common use case is storing images but you can also use it for documents, videos, music, and any other binary data (up to 10 megabytes).

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

(ParseFile允许您在云中存储应用程序文件,否则太大或者难于适应普通ParseObject。最常见的用例是存储图像,但您还可以使用它为文档、视频、音乐和其他任何二进制数据(10 mb)。

开始使用ParseFile是容易的。首先,你需要有数据在byte[],然后创建一个ParseFile形式与它。在这个例子中,我们将只使用一个字符串:)

byte[] data ="Working at Parse is great!".getBytes();

ParseFile file =newParseFile("resume.txt", data);

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

(注意在这个例子中,我们把文件命名为resume.txt.有两个注意事项:)

· You don't need to worry about filename collisions. Each upload gets a unique identifier so there's no problem with uploading multiple files named resume.txt.

(你不需要担心文件名冲突。每上传一个唯一的标识符是没有问题的,上传多个文件命名为resume.txt。)

· It's important that you give a name to the file that has a file extension. This lets Parse figure out the file type and handle it accordingly. So, if you're storing PNG images, make sure your filename ends with .png.

(重要的是你给一个名称的文件,有一个文件扩展名。这让解析图的文件类型和相应的处理。所以,如果你存储PNG图像,确保你的文件名以 .png结尾。)

Next you'll want to save the file up to the cloud. As with ParseObject, there are many variants of the save method you can use depending on what sort of callback and error handling suits you.

(接下来你要保存文件到云。与ParseObject,有许多不同的保存方法可以使用取决于你适合什么样的回调和错误处理。)

file.saveInBackground();

Finally, after the save completes, you can associate a ParseFile onto a ParseObject just like any other piece of data:

(最后,保存完成后,你可以将一个 ParseFile关联到ParseObject 就像任何其他的数据块:)

ParseObject jobApplication =newParseObject("JobApplication");

jobApplication.put("applicantName","Joe Smith");

jobApplication.put("applicantResumeFile", file);

jobApplication.saveInBackground();

Retrieving it back involves calling one of the getData variants on the ParseObject. Here we retrieve the resume file off another JobApplication object:

(检索返回涉及到调用ParseObject的变体之一getData。 这里我们检索的简历文件从另一个JobApplication对象:)

ParseFile applicantResume = (ParseFile)anotherApplication.get("applicantResumeFile");

applicantResume.getDataInBackground(newGetDataCallback() {

  publicvoiddone(byte[] data, ParseException e) {

    if(e ==null) {

      // data has the bytes for the resume

    }else{

      // something went wrong

    }

  }

});

Just like on ParseObject, you will most likely want to use the background version of getData.

(就像ParseObject一样,你很可能希望使用背景版的getData。)

Progress(进程)

It's easy to get the progress of both uploads and downloads using ParseFile by passing a ProgressCallback to saveInBackground andgetDataInBackground. For example:

(很容易得到进程的上传和下载都使用一个 ParseFile通过一个ProgressCallback到saveInBackground 和getDataInBackground。 例如:)

byte[] data ="Working at Parse is great!".getBytes();

ParseFile file =newParseFile("resume.txt", data);

 

file.saveInBackground(newSaveCallback() {

  publicvoiddone(ParseException e) {

    // Handle success or failure here ...

  }

},newProgressCallback() {

  publicvoiddone(Integer percentDone) {

    // Update your progress spinner here. percentDone will be between 0 and 100.

  }

});

Analytics(分析)

Our initial analytics hook allows you to track your application being launched. By adding the following line to the onCreate method of your main Activity, you'll begin to collect data on when and how often your application is opened.

(我们的初步分析允许你跟踪应用程序被启动。通过添加以下行onCreate方法你的主要活动,你会开始收集数据在何时以及多久打开您的应用程序一次。)

ParseAnalytics.trackAppOpened(getIntent());

Graphs and breakdowns of your statistics are accessible from your app's Dashboard.

Further analytics are available around push notification delivery and open rates. Take a look at the Tracking Pushes and App Opens subsection of our Push Guide for more detailed information on handling notification payloads and push-related callbacks.

(你的统计图和故障都可以从你的应用程序的仪表板访问。

进一步分析可以在推送通知交货和开放率。看一看跟踪推动和应用程序打开分段Tracking Pushes and App Opens subsection 我们的推动引导更多详细信息处理通知有效载荷和推动相关回调。)

Push Notifications(消息推送)

To learn more about push check out our Push Notification Guide!

Users(用户)

At the core of many apps, there is a notion of user accounts that lets users access their information in a secure manner. We provide a specialized user class called ParseUser that automatically handles much of the functionality required for user account management.

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

ParseUser is a subclass of the ParseObject, and has all the same features, such as flexible schema, automatic persistence, and a key value interface. All the methods that are on ParseObject also exist in ParseUser. The difference is that ParseUser has some special additions specific to user accounts.

(很多应用程序的核心,有一个概念的用户账户,用户可以访问自己的信息在一个安全的方式。我们提供一个专门的用户类称为ParseUser自动处理许多必需的功能用户帐户管理。

与这节课,你将能够添加用户帐户的功能在你的应用程序。

ParseUser ParseObject的一个子类,所有相同的特性,如灵活的模式,自动持久性和一个键值的接口。所有的方法,在ParseObject ParseUser也存在。 不同的是,ParseUser有一些特别添加特定于用户帐户。)

Properties(属性)

ParseUser has several properties that set it apart from ParseObject:

(ParseUser有几个属性,它有别于ParseObject的设置:)

· username: The username for the user (required).

(用户名:用户名的用户(需要)。)

· password: The password for the user (required on sign up).

(密码:用户的密码(需要注册)。)

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

(电子邮件:电子邮件地址的用户(可选)。)

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

(我们将通过其中的每个细节当我们运行通过各种用例的用户。记住,如果你设置的用户名和email使用setter,你不需要把它设置使用put方法。)

Signing Up(注册)

The first thing your app will do is probably ask the user to sign up. The following code illustrates a typical sign up:

(首先要做的就是你的应用程序可能要求用户注册。下面的代码演示了一个典型的注册:)

ParseUser user =newParseUser();

user.setUsername("my name");

user.setPassword("my pass");

user.setEmail("email@example.com");

 

// other fields can be set just like with ParseObject

user.put("phone","650-253-0000");

 

user.signUpInBackground(newSignUpCallback() {

  publicvoiddone(ParseException e) {

    if(e ==null) {

      // Hooray! Let them use the app now.

    }else{

      // Sign up didn't succeed. Look at the ParseException

      // to figure out what went wrong

    }

  }

});

This call will asynchronously create a new user in your Parse App. Before it does this, it checks to make sure that both the username and email are unique. Also, it securely hashes the password in the cloud. We never store passwords in plaintext, nor will we ever transmit passwords back to the client in plaintext.

(这个调用将异步地创建一个新用户在你的解析程序。在它检查之前,以确保两者的用户名和电子邮件是独一无二的。同时,它安全散列密码在云中。我们从来没有在明文保存密码,并且永远也不会回到客户机传输明文密码。)

Note that we used the signUpInBackground method, not the saveInBackground method. New ParseUsers should always be created using the signUpInBackground (or signUp) method. Subsequent updates to a user can be done by calling save.

(注意,我们使用了signUpInBackground方法,而不是saveInBackground方法。 创建新ParseUsers应该总是使用signUpInBackground(或注册)方法。 后续更新用户可以通过调用save.)

The signUpInBackground method comes in various flavors, with the ability to pass back errors, and also synchronous versions. As usual, we highly recommend using the asynchronous versions when possible, so as not to block the UI in your app. You can read more about these specific methods in our API docs.

(signUpInBackground的方法有很多种,有能力通过返回错误,并同步版本。像往常一样,我们强烈建议如果可能的话使用异步版本,以免阻塞UI在你的应用程序中,你可以阅读更多关于这些特定的方法在我们的API文档 API docs.)

If a signup isn't successful, you should read the error object that is returned. The most likely case is that the username or email has already been taken by another user. You should clearly communicate this to your users, and ask them try a different username.

(如果注册不成功,你应该阅读错误对象返回。最可能的情况是,用户名或电子邮件已经被另一个用户使用。你应该清楚地传达给你的用户,并叫他们尝试一个不同的用户名。)

You are free to use an email addresses as the username. Simply ask your users to enter their email, but fill it in the username property — ParseUser will work as normal. We'll go over how this is handled in the reset password section.

(你可以免费使用电子邮件地址作为用户名。只是问问你的用户输入他们的电子邮件,但它填上用户名属性——ParseUser将正常工作。我们来检查这是如何处理在重置密码部分。)

Logging In(登录)

Of course, after you allow users to sign up, you need be able to let them log in to their account in the future. To do this, you can use the class method logInInBackground.

(当然,在你允许用户注册,在将来你需要能够让他们登录到自己的帐户。要做到这一点,您可以使用类的方法logInInBackground。)

ParseUser.logInInBackground("Jerry","showmethemoney",newLogInCallback() {

  publicvoiddone(ParseUser user, ParseException e) {

    if(user !=null) {

      // Hooray! The user is logged in.

    }else{

      // Signup failed. Look at the ParseException to see what happened.

    }

  }

});

Verifying Emails(核查emails)

Enabling email verification in an application's settings allows the application to reserve part of its experience for users with confirmed email addresses. Email verification adds the emailVerified key to the ParseUser object. When a ParseUser's email is set or modified,emailVerified is set to false. Parse then emails the user a link which will set emailVerified to true.

(启用电子邮件验证应用程序的设置允许应用程序保留的部分经验,为用户提供确认电子邮件地址。电子邮件验证添加emailVerified 到ParseUser。 当一个ParseUser的电子邮件被设置或修改,emailVerified被设为false。 然后解析电子邮件用户的联系,将emailVerified设置为true。)

There are three emailVerified states to consider:

(有三个emailVerified声明需要考虑:)

true - the user confirmed his or her email address by clicking on the link Parse emailed them. ParseUsers can never have a truevalue when the user account is first created.

(true——用户证实了他或她的电子邮件地址点击链接解析邮件他们。ParseUsers永远有一个truevalue当用户账户第一次被创建。)

false - at the time the ParseUser object was last fetched, the user had not confirmed his or her email address. If emailVerified isfalse, consider calling fetch() on the ParseUser.

(false——当时,ParseUser对象最后被获取,用户没有证实他或她的电子邮件地址。如果emailVerified isfalse,考虑调用 fetch()在 ParseUser.中。)

7 missing - the ParseUser was created when email verification was off or the ParseUser does not have an email.

(失踪——ParseUser时创建电子邮件验证关闭或ParseUser没有电子邮件。)

Current User(当前用户)

It would be bothersome if the user had to log in every time they open your app. You can avoid this by using the cached currentUserobject.

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

(这将是令人讨厌的,如果用户已经登录,每次打开你的应用,你可以避免通过使用缓存的currentUserobject。

每当你使用任何注册或登录方法,用户缓存的磁盘上。你可以把这个缓存作为一个会话,并自动假设用户登录:)

ParseUser currentUser = ParseUser.getCurrentUser();

if(currentUser !=null) {

  // do stuff with the user

}else{

  // show the signup or login screen

}

You can clear the current user by logging them out:

(你可以通过注销来清除当前的用户:)

ParseUser.logOut();

ParseUser currentUser = ParseUser.getCurrentUser();// this will now be null

Anonymous Users(匿名用户)

Being able to associate data and objects with individual users is highly valuable, but sometimes you want to be able to do this without forcing a user to specify a username and password.

An anonymous user is a user that can be created without a username and password but still has all of the same capabilities as any other ParseUser. After logging out, an anonymous user is abandoned, and its data is no longer accessible.

(能够关联数据和对象与个人用户是非常宝贵的,但有时你希望能够做到这一点而不强迫用户指定一个用户名和密码。

一个匿名用户可以创建一个用户,该用户没有用户名和密码,但仍有所有相同的功能作为任何其他ParseUser。注销后,一个匿名用户抛弃,和它的数据不再是可访问的。)

You can create an anonymous user using ParseAnonymousUtils:

(您可以创建一个匿名用户使用ParseAnonymousUtils:)

ParseAnonymousUtils.logIn(newLogInCallback() {

  @Override

  publicvoiddone(ParseUser user, ParseException e) {

    if(e !=null) {

      Log.d("MyApp","Anonymous login failed.");

    }else{

      Log.d("MyApp","Anonymous user logged in.");

    }

  }

});

You can convert an anonymous user into a regular user by setting the username and password, then calling signUp(), or by logging in or linking with a service like Facebook or Twitter. The converted user will retain all of its data. To determine whether the current user is an anonymous user, you can check ParseAnonymousUtils.isLinked():

(你可以转换一个匿名用户进入普通用户通过设置用户名和密码,然后调用注册(),或通过登录或联系服务像 Facebook or Twitter。 转换后的用户将保留它的所有数据。确定当前用户是一个匿名用户,您可以检查ParseAnonymousUtils.isLinked():)

if(ParseAnonymousUtils.isLinked(ParseUser.getCurrentUser())) {

  enableSignUpButton();

}else{

  enableLogOutButton();

}

Anonymous users can also be automatically created for you without requiring a network request, so that you can begin working with your user immediately when your application starts. When you enable automatic anonymous user creation at application startup,ParseUser.getCurrentUser() will never be null. The user will automatically be created in the cloud the first time the user or any object with a relation to the user is saved. Until that point, the user's object ID will be null. Enabling automatic user creation makes associating data with your users painless. For example, in your Application.onCreate() method, you might write:

(匿名用户可以自动为您创建不需要网络的要求,这样你就可以开始使用您的用户立即当你的应用程序启动。当启用了自动匿名用户创建应用程序启动时,ParseUser.getCurrentUser()永远不会空。用户将自动被创建在云第一次用户或任何对象与关系到用户保存。直到此时,用户的对象ID将null。启用自动用户创建使关联数据与用户无痛。例如,在你的应用程序oncreate()方法,你可能会写:)

ParseUser.enableAutomaticUser();

ParseUser.getCurrentUser().increment("RunCount");

ParseUser.getCurrentUser().saveInBackground();

Security For User Objects(用户对象的安全)

The ParseUser class is secured by default. Data stored in a ParseUser can only be modified by that user. By default, the data can still be read by any client. Thus, some ParseUser objects are authenticated and can be modified, whereas others are read-only.

Specifically, you are not able to invoke any of the save or delete type methods unless the ParseUser was obtained using an authenticated method, like logIn or signUp. This ensures that only the user can alter their own data.

(ParseUser类的默认担保。 数据存储在一个ParseUser只能由该用户修改。默认情况下,数据仍然可以读取任何客户机。因此,一些ParseUser对象是经过身份验证的,可以修改的,而其他人是只读的。

具体地说,你不能够调用任何保存或删除类型方法,除非得到ParseUser使用一个经过验证的方法,如登录或注册。这可以确保只有用户可以修改自己的数据。)

The following illustrates this security policy:(下面的说明了这个安全策略:)

ParseUser user = ParseUser.logIn("my_username","my_password");

user.setUsername("my_new_username");// attempt to change username

user.saveInBackground();// This succeeds, since the user was authenticated on the device

 

// Get the user from a non-authenticated manner

ParseQuery<ParseUser> query = ParseUser.getQuery();

query.getInBackground(user.getObjectId(),newGetCallback<ParseUser>() {

  publicvoiddone(ParseUser object, ParseException e) {

    object.setUsername("another_username");

 

    // This will throw an exception, since the ParseUser is not authenticated

    object.saveInBackground();

  }

});

The ParseUser obtained from getCurrentUser() will always be authenticated.

If you need to check if a ParseUser is authenticated, you can invoke the isAuthenticated() method. You do not need to checkisAuthenticated() with ParseUser objects that are obtained via an authenticated method.

(ParseUser从 getCurrentUser()获得总是会被验证。

如果你需要检查是否一个ParseUser通过身份验证,您可以调用isAuthenticated()方法。你不需要checkisAuthenticated()与ParseUser对象通过一个经过验证的方法获得。)

Security for Other Objects(其他对象的安全)

The same security model that applies to the ParseUser can be applied to other objects. For any object, you can specify which users are allowed to read the object, and which users are allowed to modify an object. To support this type of security, each object has an access control list, implemented by the ParseACL class.

The simplest way to use a ParseACL is to specify that an object may only be read or written by a single user. To create such an object, there must first be a logged in ParseUser. Then, new ParseACL(user) generates a ParseACL that limits access to that user. An object's ACL is updated when the object is saved, like any other property. Thus, to create a private note that can only be accessed by the current user:

(相同的安全模型,该模型适用于ParseUser可以应用到其他对象。对于任何对象,您可以指定允许哪些用户阅读对象,并允许哪些用户修改一个对象。为了支持这种类型的安全,每一个对象都有一个访问控制列表access control list,ParseACL类实现的。

最简单的方法使用一个ParseACL是指定一个对象可能只是读或写的一个单一的用户。创建这样的一个对象,就必须首先是一个登录ParseUser。然后,新ParseACL(用户)生成一个ParseACL限制访问用户。一个对象的ACL的更新当对象是保存的,就像任何其他财产。因此,创建一个私人注意,只能访问当前用户:)

ParseObject privateNote =newParseObject("Note");

privateNote.put("content","This note is private!");

privateNote.setACL(newParseACL(ParseUser.getCurrentUser()));

privateNote.saveInBackground();

This note will then only be accessible to the current user, although it will be accessible to any device where that user is signed in. This functionality is useful for applications where you want to enable access to user data 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 ParseACL using setReadAccess andsetWriteAccess. For example, let's say you have a message that will be sent to a group of several users, where each of them have the rights to read and delete that message:

(这个注意将可发现当前用户,尽管它将可以访问任何设备,用户是在哪里签署。这个功能是有用的应用程序,您想启用访问用户数据跨多个设备,像一个个人todo列表。

权限也可以授予在每个用户的基础上。你可以添加到一个ParseACL权限单独使用setReadAccess andsetWriteAccess。 例如,假设您有一个消息被发送到一组几个用户,每个人有权阅读和删除消息:)

ParseObject groupMessage =newParseObject("Message");

ParseACL groupACL =newParseACL();

     

// userList is an Iterable<ParseUser> with the users we are sending this message to.

for(ParseUser user : userList) {

  groupACL.setReadAccess(user,true);

  groupACL.setWriteAccess(user,true); 

}

 

groupMessage.setACL(groupACL);

groupMessage.saveInBackground();

You can also grant permissions to all users at once using setPublicReadAccess and setPublicWriteAccess. This allows patterns like posting comments on a message board. For example, to create a post that can only be edited by its author, but can be read by anyone:

(你也可以把权限授予所有用户在使用一次setPublicReadAccess和setPublicWriteAccess。 这允许模式像在留言板上发表评论。例如,要创建一个帖子,只能编辑作者,但任何人都可以读取:)

ParseObject publicPost =newParseObject("Post");

ParseACL postACL =newParseACL(ParseUser.getCurrentUser());

postACL.setPublicReadAccess(true);

publicPost.setACL(postACL);

publicPost.saveInBackground();

To help ensure that your users' data is secure by default, you can set a default ACL to be applied to all newly-created ParseObjects:

(为了确保你的用户的数据是安全的,你可以设置默认默认ACL是适用于所有新ParseObjects:)

ParseACL.setDefaultACL(defaultACL,true);

In the code above, the second parameter to setDefaultACL tells Parse to ensure that the default ACL assigned at the time of object creation allows read and write access to the current user at that time. Without this setting, you would need to reset the defaultACL every time a user logs in or out so that the current user would be granted access appropriately. With this setting, you can ignore changes to the current user until you explicitly need to grant different kinds of access.

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

(在上面的代码中,第二个参数setDefaultACL告诉解析,确保默认ACL分配在对象创建允许读和写访问当前用户在那个时间。没有这个设置,您将需要重置defaultACL每次用户登录或离开,这样当前用户将获得适当的访问。这个设置,你可以忽略更改当前用户直到你明确需要授予不同的访问。

默认的acl易于创建应用程序,遵循通用的访问模式。一个应用程序像Twitter,例如,用户内容通常是可见的世界,可能会设置一个默认的ACL如:)

ParseACL defaultACL =newParseACL();

defaultACL.setPublicReadAccess(true);

ParseACL.setDefaultACL(defaultACL,true);

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

(对于一个应用程序(如Dropbox,用户的数据只能通过用户本身,除非明确允许,你将提供了一个默认的ACL,只有当前用户拥有访问:)

ParseACL.setDefaultACL(newParseACL(),true);

An application that logs data to Parse but doesn't provide any user access to that data would instead deny access to the current user while providing a restrictive ACL:

(一个应用程序日志数据解析但不提供任何用户访问这些数据将相反否认对当前用户的访问,同时提供一个限制性的ACL:)

ParseACL.setDefaultACL(newParseACL(),false);

Operations that are forbidden, such as deleting an object that you do not have write access to, result in aParseException.OBJECT_NOT_FOUND error code. For security purposes, this prevents clients from distinguishing which object ids exist but are secured, versus which object ids do not exist at all.

(禁止的操作,比如删除一个对象,你没有写访问,导致aParseException。对象没有找到错误代码。出于安全目的,这样可以防止客户从区分对象id存在但担保对象id,而不存在。)

Resetting Passwords(重设密码)

It's a fact that as soon as you introduce passwords into a system, users will forget them. In such cases, our library provides a way to let them securely reset their password.

To kick off the password reset flow, ask the user for their email address, and call:

(这是一个事实,只要你介绍密码进入系统,用户将会忘记它们。在这种情况下,我们的库提供了一种方法,让他们安全地重置密码。

启动密码重置流程,要求用户输入他们的电子邮件地址和电话:)

ParseUser.requestPasswordResetInBackground("myemail@example.com",

                                           newRequestPasswordResetCallback() {

  publicvoiddone(ParseException e) {

    if(e ==null) {

      // An email was successfully sent with reset instructions.

    }else{

      // Something went wrong. Look at the ParseException to see what's up.

    }

  }

});

This will attempt to match the given email with the user's email or username field, and will send them a password reset email. By doing this, you can opt to have users use their email as their username, or you can collect it separately and store it in the email field.

(这将尝试匹配给定的电子邮件与用户的电子邮件或用户名字段,并将密码重置邮件发给他们。通过这样做,您可以选择有用户使用他们的电子邮件作为用户名,或者你可以收集它,并将它存储在单独的电子邮件字段。)

The flow for password reset is as follows:(密码重置的流程如下:)

8 User requests that their password be reset by typing in their email.

    (用户请求被重置密码输入在他们的电子邮件。)

Parse sends an email to their address, with a special password reset link.(解析发送邮件到他们的地址,用一种特殊的密码重置链接。)

9 User clicks on the reset link, and is directed to a special Parse page that will allow them type in a new password.

  (用户单击重置链接,指向一个特殊解析页面,这样将会使他们在一个新密码。)

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

(用户输入一个新密码。密码已被重置为它们指定一个值。)

Note that the messaging in this flow will reference your app by the name that you specified when you created this app on Parse.

(请注意,消息在这个流程将参考您的应用程序的名称时指定了这个应用程序解析。)

Querying(询问)

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

(查询用户,需要使用特殊的用户查询:)

ParseQuery<ParseUser> query = ParseUser.getQuery();

query.whereEqualTo("gender","female");

query.findInBackground(newFindCallback<ParseUser>() {

  publicvoiddone(List<ParseUser> objects, ParseException e) {

    if(e ==null) {

        // The query was successful.

    }else{

        // Something went wrong.

    }

  }

});

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

(此外,您可以使用去得到一个ParseUser通过id。)

Associations(协议)

Associations involving a ParseUser work right of the box. For example, let's say you're making a blogging app. To store a new post for a user and retrieve all their posts:

(涉及ParseUser协议工作正确的盒子。例如,让我们说你做一个博客应用。存储一个新的职位对于一个用户和检索所有的帖子:)

ParseUser user = ParseUser.getCurrentUser();

 

// Make a new post

ParseObject post =newParseObject("Post");

post.put("title","My New Post");

post.put("body","This is some great content.");

post.put("user", user);

post.saveInBackground();

 

// Find all posts by the current user

ParseQuery<ParseObject> query = ParseQuery.getQuery("Post");

query.whereEqualTo("user", user);

query.findInBackground(newFindCallback<ParseObject>() { ... });

Users in the Data Browser(用户在数据浏览器)

The User class is a special class that is dedicated to storing ParseUser objects. In the data browser, you'll see a little person icon next to the User class:

(用户类是一个特殊的类,它致力于存储ParseUser对象。在数据浏览器,你会看到有个小人图标旁边的用户类:)

Roles(角色)

As your app grows in scope and user-base, you may find yourself needing more coarse-grained control over access to pieces of your data than user-linked ACLs can provide. To address this requirement, Parse supports a form of Role-based Access Control. Roles provide a logical way of grouping users with common access privileges to your Parse data. Roles are named objects that contain users and other roles. Any permission granted to a role is implicitly granted to its users as well as to the users of any roles that it contains.

(作为你的应用扩大范围和用户基础,你可能发现自己需要更粗粒度的控制你的数据访问块比用户联系acl可以提供。为了处理这个需求,解析支持形式的基于角色的访问控制Role-based Access Control。 角色提供一种合乎逻辑的方式与普通的用户访问权限分组你解析数据。角色命名的对象,包含用户和其他角色。任何权限授给一个角色是隐式授予用户以及用户的任何角色,它包含。)

For example, in your application with curated content, you may have a number of users that are considered "Moderators" and can modify and delete content created by other users. You may also have a set of users that are "Administrators" and are allowed all of the same privileges as Moderators, but can also modify the global settings for the application. By adding users to these roles, you can ensure that new users can be made moderators or administrators, without having to manually grant permission to every resource for each user.

(例如,在您的应用程序和策划内容,你可能有一个数量的用户,被视为“版主”,可以修改和删除其他用户创建的内容。你也可以有一组用户“管理员”,允许所有相同的特权作为版主,但是也可以修改全局设置的应用程序。通过将用户添加到这些角色,您可以确保新用户可以版主或管理员,而不必手动授予许可为每个用户每一个资源。)

We provide a specialized class called ParseRole that represents these role objects in your client code. ParseRole is a subclass of ParseObject, and has all of the same features, such as a flexible schema, automatic persistence, and a key value interface. All the methods that are on ParseObject also exist on ParseRole. The difference is that ParseRole has some additions specific to management of roles.

(我们提供一个专门的类称为ParseRole代表这些角色对象在您的客户端代码。ParseRole是ParseObject的子类,并且所有相同的特性,如灵活的模式,自动持久性和一个键值的接口。所有的方法,在ParseObject也存在于ParseRole。 不同的是,ParseRole有一些添加特定于管理的角色。)

Properties(性能)

ParseRole has several properties that set it apart from ParseObject:

(ParseRole有几个属性,它有别于ParseObject设置:)

· name: The name for the role. This value is required, and can only be set once as a role is being created. The name must consist of alphanumeric characters, spaces, -, or _. This name will be used to identify the Role without needing its objectId.

(名称:角色的名称。这个值是必需的,并且只能设置一次作为一个角色被创建。这个名称必须包含字母数字字符,空格,-,或_。这个名字将被用来识别角色不需要其objectId。)

· users: A relation to the set of users that will inherit permissions granted to the containing role.

(用户:一个关系relation的固定用户,将继承权限授予包含角色。)

· roles: A relation to the set of roles whose users and roles will inherit permissions granted to the containing role.

(角色:一个关系relation到组角色的用户和角色将继承权限授予包含角色。)

Security for Role Objects(角色对象的安全)

The ParseRole uses the same security scheme (ACLs) as all other objects on Parse, except that it requires an ACL to be set explicitly. Generally, only users with greatly elevated privileges (e.g. a master user or Administrator) should be able to create or modify a Role, so you should define its ACLs accordingly. Remember, if you give write-access to a ParseRole to a user, that user can add other users to the role, or even delete the role altogether.

(这个ParseRole使用相同的安全方案(ACL)作为所有其他对象解析,除了它需要显式地设置ACL。一般来说,只有用户大大提升特权(例如一个主用户或管理员)应该能够创建或修改一个角色,所以你应该定义相应的acl。记住,如果你给一个ParseRole写访问一个用户,该用户可以添加其他用户角色,甚至删除角色完全。)

To create a new ParseRole, you would write:(创建一个新的ParseRole,你会写:)

// By specifying no write privileges for the ACL, we can ensure the role cannot be altered.

ParseACL roleACL =newParseACL();

roleACL.setPublicReadAccess(true);

ParseRole role =newParseRole("Administrator", roleACL);

role.saveInBackground();

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

(To create a new ParseRole, you would write:)

ParseRole role =newParseRole(roleName, roleACL);

for(ParseUser user : usersToAddToRole) {

  role.getUsers().add(user)

}

for(ParseRole childRole : rolesToAddToRole) {

  role.getRoles().add(childRole);

}

role.saveInBackground();

Take great care when assigning ACLs to your roles so that they can only be modified by those who should have permissions to modify them.

(很小心很小心当你的角色分配acl以便他们只能修改那些应该有权限来修改它们。)

Security for Other Objects(其他对象的安全)

Now that you have created a set of roles for use in your application, you can use them with ACLs to define the privileges that their users will receive. Each ParseObject can specify a ParseACL, which provides an access control list that indicates which users and roles should be granted read or write access to the object.

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

(现在,您已经创建了一组角色用于您的应用程序,您可以使用它们与acl定义特权,他们的用户将收到。每个ParseObject可以指定一个ParseACL,它提供了一个访问控制列表,显示哪个用户和角色应该授予读或写访问对象。

给一个角色读或写权限对象是直截了当的。您可以使用ParseRole:)

ParseRole moderators =/* Query for some ParseRole */;

ParseObject wallPost =newParseObject("WallPost");

ParseACL postACL =newParseACL();

postACL.setRoleWriteAccess(moderators);

wallPost.setACL(postACL);

wallPost.saveInBackground();

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

(你可以避免查询角色通过指定它的名字为ACL:)

ParseObject wallPost =newParseObject("WallPost");

ParseACL postACL =newParseACL();

postACL.setRoleWriteAccess("Moderators",true);

wallPost.setACL(postACL);

wallPost.save();

Role-based ParseACLs can also be used when specifying default ACLs for your application, making it easy to protect your users' data while granting access to users with additional privileges. For example, a moderated forum application might specify a default ACL like this:

(基于角色的ParseACLs还可以指定默认的acl时为您的应用程序,使它容易保护用户的数据,同时授予访问用户提供额外的特权。例如,一个节制的论坛应用程序可以指定一个默认的ACL如下:)

ParseACL defaultACL =newParseACL();

// Everybody can read objects created by this user

defaultACL.setPublicReadAccess(true);

// Moderators can also modify these objects

defaultACL.setRoleWriteAccess("Moderators");

// And the user can read and modify its own objects

ParseACL.setDefaultACL(defaultACL,true);

Role Hierarchy(角色继承)

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

These types of relationships are commonly found in applications with user-managed content, such as forums. Some small subset of users are "Administrators", with the highest level of access to tweaking the application's settings, creating new forums, setting global messages, and so on. Another set of users are "Moderators", who are responsible for ensuring that the content created by users remains appropriate. Any user with Administrator privileges should also be granted the permissions of any Moderator. To establish this relationship, you would make your "Administrators" role a child role of "Moderators", like this:

(如上所述,一个角色可以包含另一个,建立亲子关系的两个角色。这种关系的结果是,任何许可授予父角色是隐式授予它的所有孩子的角色。

这些类型的关系普遍存在于应用程序与用户管理的内容,比如论坛。有些小子集的用户是“管理员”,具有最高的访问级别调整应用程序的设置,创建新的论坛,设定全球信息,等等。另一组用户“版主”,负责确保内容由用户仍然是适当的。任何用户与管理员权限也应该被授予权限的主持人。建立这种关系,你会让你的“管理员”角色子角色的“版主”,像这样:)

ParseRole administrators =/* Your "Administrators" role */;

ParseRole moderators = /* Your "Moderators" role */;

moderators.getRoles().add(administrators);

moderators.saveInBackground();

Facebook Users(facebook用户)

Parse provides an easy way to integrate Facebook with your application. The Facebook SDK can be used with our SDK, and is integrated with the ParseUser class to make linking your users to their Facebook identities easy.

Using our Facebook integration, you can associate an authenticated Facebook user with a ParseUser. With just a few lines of code, you'll be able to provide a "log in with Facebook" option in your app, and be able to save their data to Parse.

(解析提供了一种简单的方法来集成Facebook与应用程序。Facebook SDK可以用于我们的SDK,结合ParseUser类使链接你的用户他们的Facebook身份容易。

使用我们的Facebook集成,您可以将一个经过验证的Facebook用户ParseUser。 只有几行代码,您将能够提供一个“登入Facebook”选项在你的应用程序,并能够拯救他们的数据来解析。)

Setup(建立)

To start using Facebook with Parse, you need to:(开始使用Facebook与解析,您需要:)

Set up a Facebook app, if you haven't already.( Set up a Facebook app,如果你还没有。)

11 Add your application's Facebook Application ID on your Parse application's settings page.

(添加应用程序的Facebook应用程序ID在你解析应用程序的设置页面。)

12 Follow Facebook's instructions for getting started with the Facebook SDK to create an app linked to the Facebook SDK. Once you get to Step 6, stop after linking the Facebook SDK project and configuring the Facebook app ID. You can use our guide to attach your Parse users to their Facebook accounts when logging in.

(遵循Facebook的指令来开始使用getting started with the Facebook SDK创建一个应用程序链接到Facebook SDK。 一旦你到达第六步,停止在连接Facebook SDK项目和配置Facebook的应用程序ID。你可以使用我们的导游附上你的解析用户的Facebook账号登录.)

Add the following where you initialize the Parse SDK in your Application.onCreate()

(添加以下你初始化解析SDK在你的应用程序oncreate())

ParseFacebookUtils.initialize("YOUR FACEBOOK APP ID");

Facebook's Android SDK provides an enhanced login experience on devices that have Facebook's official Android app installed. This allows users of apps that support Facebook login to sign in directly through the Facebook app, using credentials that are already on the device. If the Facebook app is not installed, the default dialog-based authentication will be used. Facebook calls this feature "Single sign-on," and requires you to override onActivityResult() in your calling Activity to invoke finishAuthentication().

(Facebook的Android SDK提供了一个增强的登录体验设备,有Facebook的官方安卓应用Facebook's official Android app安装。 这允许用户的应用,支持Facebook登录登录,直接通过Facebook的应用程序,使用凭证已经在设备上。如果Facebook的应用程序没有安装,默认将使用基于对话框的验证。Facebook称这个功能“单点登录”,并要求您覆盖onActivityResult()调用活动来调用finishAuthentication()。)

@Override

protectedvoidonActivityResult(intrequestCode,intresultCode, Intent data) {

  super.onActivityResult(requestCode, resultCode, data);

  ParseFacebookUtils.finishAuthentication(requestCode, resultCode, data);

}

If your Activity is already using onActivityResult(), you can avoid requestCode collisions by calling the versions of link() andlogIn() that take an activityCode parameter and specifying a code you know to be unique. Otherwise, a sensible defaultactivityCode will be used.

If you encounter any issues that are Facebook-related, a good resource is the official Facebook SDK for Android page.

Parse is compatible with v3.0 of the Facebook SDK for Android.

There are two main ways to use Facebook with your Parse users: (1) logging in as a Facebook user and creating a ParseUser, or (2) linking Facebook to an existing ParseUser.

(如果你的活动已经使用onActivityResult(),您可以避免碰撞requestCode通过调用版本的链接()andlogIn(),把一个activityCode参数并指定一个代码你知道是独特的。否则,一个明智的defaultactivityCode将被使用。

如果你遇到任何问题,Facebook相关,一个好的资源是官方Facebook SDK为Android页 official Facebook SDK for Android page解析兼容v3.0的Facebook SDK为Android。

有两种主要的方式来使用Facebook和你解析用户:(1)测井作为Facebook用户和创建一个ParseUser,或(2)连接到一个现有的ParseUser Facebook。)

Login & Signup(登录和建立)

ParseFacebookUtils provides a way to allow your ParseUsers to log in or sign up through Facebook. This is accomplished using thelogIn() method:

(ParseFacebookUtils提供了一种方法来让你的ParseUsers登录或注册通过Facebook。 这是通过使用thelogIn()方法:)

ParseFacebookUtils.logIn(this,newLogInCallback() {

  @Override

  publicvoiddone(ParseUser user, ParseException err) {

    if(user ==null) {

      Log.d("MyApp","Uh oh. The user cancelled the Facebook login.");

    }elseif(user.isNew()) {

      Log.d("MyApp","User signed up and logged in through Facebook!");

    }else{

      Log.d("MyApp","User logged in through Facebook!");

    }

  }

});

When this code is run, the following happens:

(当这段代码运行时,就会发生以下问题:)

13 The user is shown the Facebook login dialog or a prompt generated by the Facebook app.

(用户登录对话框显示Facebook或提示生成的Facebook应用程序。)

14 The user authenticates via Facebook, and your app receives a callback.

(通过Facebook的用户进行身份验证,您的应用程序接收一个回调。)

15 Our SDK receives the Facebook data and saves it to a ParseUser. If it's a new user based on the Facebook ID, then that user is created.

(我们的SDK接收Facebook的数据,并将它保存到一个ParseUser。 如果这是一个新用户基于Facebook ID,则该用户被创建。)

16 Your LogInCallback is called with the user.

In order to display the Facebook login dialogs and activities, the current Activity must be provided (often, the current activity is thiswhen calling logIn() from within the Activity) as we have done above.

You may optionally provide a collection of strings that specifies what read permissions your app requires from the Facebook user. You may specify these strings yourself, or use the constants we've provided for you in the ParseFacebookUtils.Permissions class. For example:

(你的LogInCallback叫做与用户。

为了显示Facebook登录对话框和活动,此次活动必须提供(通常,当前活动是thiswhen调用登录()在活动)正如我们上面所做的。

你可以选择提供一组字符串,指定阅读权限应用程序需要从Facebook用户。你可以指定这些字符串自己,或使用常量我们已经提供了你的ParseFacebookUtils。权限类。例如:)

ParseFacebookUtils.logIn(Arrays.asList("email", Permissions.Friends.ABOUT_ME),

        this,newLogInCallback() {

  @Override

  publicvoiddone(ParseUser user, ParseException err) {

    // Code to handle login.

  }

});

ParseUser integration doesn't require any permissions to work out of the box (ie. null or specifying no permissions is perfectly acceptable). When logging in, you can only use read permissions. See our documentation below about requesting additional permissions (read or publish). Read more about permissions on Facebook's developer guide.

(ParseUser集成不需要任何权限工作从盒子里(即。null或指定没有权限是完全可以接受的)。在登录时,您只能使用读权限。看到我们下面的文档关于请求额外权限requesting additional permissions(读或发布)。 阅读更多关于权限在Facebook的开发者指南。Read more about permissions on Facebook's developer guide.)

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

(它是由你来记录任何您需要的数据从Facebook用户在他们验证。为了实现这个目标,你需要做一个图查询通过

do a graph query via Facebook's SDK.

Linking(联系)

If you want to associate an existing ParseUser to a Facebook account, you can link it like so:(如果你想将一个现有的ParseUser Facebook帐户,您可以链接它像这样:)

if(!ParseFacebookUtils.isLinked(user)) {

  ParseFacebookUtils.link(user,this,newSaveCallback() {

    @Override

    publicvoiddone(ParseException ex) {

      if(ParseFacebookUtils.isLinked(user)) {

        Log.d("MyApp","Woohoo, user logged in with Facebook!");

      }

    }

  });

}

The steps that happen when linking are very similar to log in. The difference is that on successful login, the existing ParseUser is updated with the Facebook information. Future logins via Facebook will now log the user into their existing account.

(链接时发生的步骤非常类似于登录。不同的是,成功登录后,现有的ParseUser与Facebook的更新信息。未来的登录Facebook现在将日志用户到他们现有的帐户。)

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

(如果你想分开Facebook从一个用户,只需这样做:)

ParseFacebookUtils.unlinkInBackground(user,newSaveCallback() {

  @Override

  publicvoiddone(ParseException ex) {

    if(ex ==null) {

      Log.d("MyApp","The user is no longer associated with their Facebook account.");

    }

  }

});

Or if you are handling threading yourself, you can call unlink() directly like this:(或者如果你处理线程自己,你可以打电话直接unlink():)

try{

  ParseFacebookUtils.unlink(user);

  Log.d("MyApp","The user is no longer associated with their Facebook account.");

}catch(ParseException e) {

}

Requesting Permissions(请求权限)

As of v3.0 of the Facebook SDK, read and publish permissions must be requested separately. ParseFacebookUtils.logIn() andParseFacebookUtils.link() only allow you to request read permissions. To request additional permissions, you may callParseFacebookUtils.getSession().requestNewReadPermissions() orParseFacebookUtils.getSession().requestNewPublishPermissions(). For more information about requesting new permissions, please see Facebook's API documentation for these functions.

After successfully retrieving new permissions, please call ParseFacebookUtilities.saveLatestSessionData(), which will save any changes to the session token back to the ParseUser and ensure that this session data follows the user wherever it logs in.

(截至v3.0的Facebook SDK,阅读和发布权限必须要求分别。andParseFacebookUtils.link ParseFacebookUtils.logIn()()只允许你请求读权限。 要求额外的权限,你可以callParseFacebookUtils.getSession()()().requestNewReadPermissions orParseFacebookUtils.getSession .requestNewPublishPermissions()。 为更多的信息关于请求新的权限,请看到Facebook的API文档为这些函数

Facebook's API documentation for these functions.

在成功地检索新的权限,请打电话给ParseFacebookUtilities.saveLatestSessionData(),它将保存任何更改会话令牌回ParseUser和确保这个会话数据遵循用户无论它登录。)

Facebook SDK and Parse(facebook SDK和解析)

The Facebook Android SDK provides a number of helper classes for interacting with Facebook's API. Generally, you will use the Request class to interact with Facebook on behalf of your logged-in user. You can read more about the Facebook SDK here.

Our library manages the user's Session object for you. You can simply call ParseFacebookUtils.getSession() to access the session instance, which can then be passed to Requests.

(Facebook提供了许多Android SDK helper类进行交互与Facebook的API。 通常,您将使用请求类与Facebook代表您的登录用户。你可以阅读更多关于Facebook SDK这里

 You can read more about the Facebook SDK here.

我们的图书馆管理用户的会话对象。你可以简单的叫ParseFacebookUtils.getSession()来访问会话实例,它可以被传递给请求。)

Twitter Users(Twitter用户)

As with Facebook, Parse also provides an easy way to integrate Twitter authentication into your application. The Parse SDK provides a straightforward way to authorize and link a Twitter account to your ParseUsers. With just a few lines of code, you'll be able to provide a "log in with Twitter" option in your app, and be able to save their data to Parse.

(与Facebook,解析也提供了一个简单的方法来整合Twitter验证到您的应用程序。解析SDK提供了一种直接的方式,授权和链接到你的ParseUsers一个Twitter帐户。只有几行代码,您将能够提供一个“与Twitter登录”选项在你的应用程序,并能够拯救他们的数据来解析。)

Setup(建立)

To start using Twitter with Parse, you need to:(开始使用Twitter与解析,您需要:)

Set up a Twitter app, if you haven't already.(Set up a Twitter app,如果你还没有。)

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

(添加应用程序的Twitter用户密钥在你的解析程序的设置页面。)

18 When asked to specify a "Callback URL" for your Twitter app, please insert a valid URL. This value will not be used by your iOS or Android application, but is necessary in order to enable authentication through Twitter.

(当被要求指定一个“回调URL”你的Twitter应用程序,请插入一个有效的URL。这个值就不能使用你的iOS和Android应用程序,但仍有必要为了启用身份验证通过Twitter。)

Add the following where you initialize the Parse SDK in your Application.onCreate()

(添加以下你初始化解析SDK在你的应用程序oncreate())

ParseTwitterUtils.initialize("YOUR CONSUMER KEY","YOUR CONSUMER SECRET");

If you encounter any issues that are Twitter-related, a good resource is the official Twitter documentation.

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

(如果你遇到任何问题,都与Twitter相关,一个好的资源是官方Twitter文档official Twitter documentation.有两种主要的方式来使用Twitter和你解析用户:(1)登录作为Twitter用户和创建一个ParseUser,或(2)连接到一个现有的ParseUser Twitter。)

Login & Signup(登录和建立)

ParseTwitterUtils provides a way to allow your ParseUsers to log in or sign up through Twitter. This is accomplished using the logIn()method:

(ParseTwitterUtils提供了一种方法来让你的ParseUsers登录或注册通过Twitter。 这是通过使用登录()方法:)

ParseTwitterUtils.logIn(this,newLogInCallback() {

  @Override

  publicvoiddone(ParseUser user, ParseException err) {

    if(user ==null) {

      Log.d("MyApp","Uh oh. The user cancelled the Twitter login.");

    }elseif(user.isNew()) {

      Log.d("MyApp","User signed up and logged in through Twitter!");

    }else{

      Log.d("MyApp","User logged in through Twitter!");

    }

  }

});

When this code is run, the following happens:

(当这段代码运行时,就会发生以下问题:)

19 The user is shown the Twitter login dialog.

(用户登录对话框显示Twitter。)

20 The user authenticates via Twitter, and your app receives a callback.

(通过Twitter的用户进行身份验证,您的应用程序接收一个回调。)

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

(我们的SDK接收Twitter数据并保存到一个ParseUser。 如果这是一个新用户基于Twitter处理,则该用户被创建。)

22 Your LogInCallback is called with the user.

In order to display the Twitter login dialogs and activities, the current Context must be provided (often, the current context is this when calling logIn() from within the Activity) as we have done above.

(你的LogInCallback叫做与用户。

为了显示Twitter登录对话框和活动,必须提供当前上下文(通常,当前上下文这是当调用登录()在活动)正如我们上面所做的。)

Linking(连接)

If you want to associate an existing ParseUser with a Twitter account, you can link it like so:(如果你想将一个现有的ParseUser与一个Twitter帐户,您可以链接它像这样:)

if(!ParseTwitterUtils.isLinked(user)) {

  ParseTwitterUtils.link(user,this,newSaveCallback() {

    @Override

    publicvoiddone(ParseException ex) {

      if(ParseTwitterUtils.isLinked(user)) {

        Log.d("MyApp","Woohoo, user logged in with Twitter!");

      }

    }

  });

}

The steps that happen when linking are very similar to log in. The difference is that on successful login, the existing ParseUser is updated with the Twitter information. Future logins via Twitter will now log the user into their existing account.

(链接时发生的步骤非常类似于登录。不同的是,成功登录后,现有的ParseUser更新Twitter的信息。未来通过Twitter登录现在将日志用户到他们现有的帐户。)

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

(如果你想分开的Twitter用户,只需这样做:)

ParseTwitterUtils.unlinkInBackground(user,newSaveCallback() {

  @Override

  publicvoiddone(ParseException ex) {

    if(ex ==null) {

      Log.d("MyApp","The user is no longer associated with their Twitter account.");

    }

  }

});

Twitter API Calls(Twitter API)

Our SDK provides a straightforward way to sign your API HTTP requests to the Twitter REST API when your app has a Twitter-linkedParseUser. To make a request through our API, you can use the Twitter singleton provided by ParseTwitterUtils:

(我们的SDK提供了一种直接的方式签署你的API的HTTP请求到Twitter REST APITwitter REST API当你的应用程序有一个Twitter-linkedParseUser。 做一个请求通过我们的API,您可以使用Twitter提供的单ParseTwitterUtils:)

HttpClient client =newDefaultHttpClient();

HttpGet verifyGet =newHttpGet(

        "https://api.twitter.com/1/account/verify_credentials.json");

ParseTwitterUtils.getTwitter().signRequest(verifyGet);

HttpResponse response = client.execute(verifyGet);

Cloud Functions(云功能)

Cloud Functions can be called from Android using ParseCloud. For example, to call the Cloud Function named hello:

(云功能可以被称为ParseCloud从Android使用。 例如,调用云函数命名你好:)

ParseCloud.callFunctionInBackground("hello",newHashMap<String, Object>(),newFunctionCallback<String>() {

  voiddone(String result, ParseException e) {

    if(e ==null) {

      // result is "Hello world!"

    }

  }

});

Take a look at the Cloud Code Guide to learn more about Cloud Functions.(看看云代码指南Cloud Code Guide学习更多关于云功能。)

GeoPoints

Parse allows you to associate real-world latitude and longitude coordinates with an object. Adding a ParseGeoPoint to a ParseObjectallows queries to take into account the proximity of an object to a reference point. This allows you to easily do things like find out what user is closest to another user or which places are closest to a user.

(解析允许你副真实世界的纬度和经度坐标与物体。添加一个ParseGeoPoint到ParseObjectallows查询来考虑到邻近的一个对象到一个参考点。 这使您可以轻松地做事情喜欢找出用户接近另一个用户或哪些地方是最接近用户。)

ParseGeoPoint

To associate a point with an object you first need to create a ParseGeoPoint. For example, to create a point with latitude of 40.0 degrees and -30.0 degrees longitude:

(把一个点和一个对象您首先需要创建一个ParseGeoPoint。例如,要创建一个点与纬度40.0度和-30.0度经度:)

ParseGeoPoint point =newParseGeoPoint(40.0, -30.0);

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

(这一点然后存储在对象作为普通字段。)

placeObject.put("location", point);

Geo Queries

Now that you have a bunch of objects with spatial coordinates, it would be nice to find out which objects are closest to a point. This can be done by adding another restriction to ParseQuery using whereNear. Getting a list of ten places that are closest to a user may look something like:

(现在,你有一群对象与空间坐标,最好能找到哪些对象正在接近一个点。这可以通过添加另一个whereNear ParseQuery限制使用。 获取一列十个地方离用户看起来像:)

ParseGeoPoint userLocation = (ParseGeoPoint) userObject.get("location");

ParseQuery<ParseObject> query = ParseQuery.getQuery("PlaceObject");

query.whereNear("location", userLocation);

query.setLimit(10);

query.findInBackground(newFindCallback<ParseObject>() { ... });

At this point nearPlaces will be an array of objects ordered by distance (nearest to farthest) from userLocation. Note that if an additionalorderByAscending()/orderByDescending() constraint is applied, it will take precedence over the distance ordering.

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

It's also possible to query for the set of objects that are contained within a particular area. To find the objects in a rectangular bounding box, add the whereWithinGeoBox restriction to your ParseQuery.

(在这一点上nearPlaces将一个对象数组下令由距离(最近最远的)从userLocation。注意,如果一个additionalorderByAscending()/ orderByDescending()约束是应用,它将优先于距离排序。

限制结果使用距离,看看whereWithinKilometers,whereWithinMiles,whereWithinRadians。

还可以查询集合对象,包含在一个特定的区域。找到对象在一个矩形边界框,添加到你的ParseQuery whereWithinGeoBox限制。)

ParseGeoPoint southwestOfSF =newParseGeoPoint(37.708813, -122.526398);

ParseGeoPoint northeastOfSF =newParseGeoPoint(37.822802, -122.373962);

ParseQuery<ParseObject> query = ParseQuery.getQuery("PizzaPlaceObject");

query.whereWithinGeoBox("location", southwestOfSF, northeastOfSF);

query.findInBackground(newFindCallback<ParseObject>() { ... });

Caveats(说明)

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

(目前有几件事情要注意:)

23 Each ParseObject class may only have one key with a ParseGeoPoint object.

(每个ParseObject类可能只有一个密钥与ParseGeoPoint对象。)

24 Points should not equal or exceed the extreme ends of the ranges. Latitude should not be -90.0 or 90.0. Longitude should not be -180.0 or 180.0. Attempting to set latitude or longitude out of bounds will cause an error.

(点不应等于或超过范围的最末端。纬度不应该是-90.0或90.0。 经度不应该是-180.0或180.0。 试图设置纬度和经度界外将导致一个错误。)

User Interface(用户界面)

At the end of the day, users of your application will be interacting with Android UI components. We provide subclasses of common UI widgets to make working with Parse data easier.

(在一天结束的时候,您的应用程序的用户将会与Android UI组件交互。我们常见的UI小部件提供的子类来让处理解析数据更容易。)

ParseQueryAdapter

To display collections of data, we provide an implementation of Adapter. Instead of using a basic ListAdapter backed by a static array of objects, our ParseQueryAdapter provides a layer of abstraction and allows you to easily display data from one of your Parse classes in your AdapterView of choice (e.g. ListView or GridView).

(显示数据的集合,我们提供一个实现适配器。而不是使用一个基本的ListAdapter由一个静态的对象数组,我们ParseQueryAdapter提供了一个抽象层,使您可以轻松地显示数据从你的一个解析类在你选择的AdapterView之间扮演着(例如。列表视图或显示数据表格)。)

To use a ParseQueryAdapter to display data in an Activity, follow the steps outlined below in your Activity's onCreate:

(使用一个ParseQueryAdapter把数据显示在一个活动,遵循下面列出的步骤在您的活动的onCreate:)

Instantiate a ParseQueryAdapter.(实例化一个ParseQueryAdapter。)

Customize it as necessary (see the below subsections for detailed instructions to display data from specific queries, change the UI of the Views to be displayed, and more).(自定义必要的(见下面的部分详细说明,显示数据从特定的查询,更改UI视图被显示,并且更多)。)

25 Set your new Adapter on your AdapterView with setAdapter().

When the AdapterView is attached to the window, your ParseQueryAdapter will automatically fetch the first set of data. This subclass simplifies the code that would otherwise be involved with:

(设置你的新适配器在你与setAdapter AdapterView之间扮演着()。

当AdapterView之间扮演着被连接到该窗口,你的ParseQueryAdapter会自动取第一组数据。 这个子类简化了代码,否则涉及:)

26 Pagination, with a row that can be tapped to load the next page.

(分页,一排,可以用来加载下一页。)

Configurable downloading and displaying of remote images within rows.(可配置的下载和显示的远程图像在行。)

27 Automatic loading and management of the Parse objects array.

(自动加载和管理对象数组的解析。)

28 Callbacks from major events in the data cycle.

Consider the following code, which sets up a very simple ParseQueryAdapter to display data in a ListView. You can be up and running with a functional ListView full of data with very little configuration.

(从重大事件回调数据周期。

考虑下面的代码,它设置一个非常简单的ParseQueryAdapter把数据显示在一个列表视图。你可以开始使用一个功能完整的数据列表视图和很少的配置。)

// Inside an Activity

publicvoidonCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);

  // Uses a layout with a ListView (id: "listview"), which uses our Adapter.

  setContentView(R.layout.main);

 

  ParseQueryAdapter<ParseObject> adapter =newParseQueryAdapter<ParseObject>(this,"Instrument");

  adapter.setTextKey("name");

  adapter.setImageKey("photo");

 

  ListView listView = (ListView) findViewById(R.id.listview);

  listView.setAdapter(adapter);

}

This view will display a list of Instruments by name. Notice all the code that we're not writing: we can skip the logic to fetch each consecutive page of results, to manually update and maintain the backing data array, to download images in the background and set the image data on UI widgets, and to handle touch events to trigger loading the next page of results.

The ParseQueryAdapter can be configured to customize what data to use, how to display it, and what to do before and after it's been fetched. Read on to see what you can do, and how to tweak a ParseQueryAdapter to fit all of your needs.

(这个视图将显示一个列表的工具的名字。注意所有的代码,我们不是写:我们可以跳过逻辑连续获取每一页的搜索结果,手动更新和维护支持数据数组,在后台下载图片,设置图像数据在UI小部件,处理触摸事件触发加载下一页的结果。

可以配置的ParseQueryAdapter定制使用哪些数据,如何显示它,以及如何做之前和之后的它被拿来。读下去,看看你能做什么,以及如何调整一个ParseQueryAdapter适合你所有的需要。)

Customizing the Query

By default, the simplest ParseQueryAdapter constructor takes a Context and a Parse class name. All ParseObjects in that class are then fetched and displayed in order of their createdAt timestamps.

To change this behavior, we drew from the functionality of an ArrayAdapter: but instead of taking in a vanilla array of objects to be displayed by the adapter, ParseQueryAdapter can also take a QueryFactory class which returns a ParseQuery you define. Pass that into the constructor, and the adapter will then use that query to determine which objects to fetch and display.

See below for an example setting up a ParseQueryAdapter to display only punk and metal bands with four or more members, ordered by number of records sold:

(默认情况下,最简单的ParseQueryAdapter构造函数接受一个上下文和解析类的名字。所有在这类ParseObjects然后获取并显示的顺序createdAt时间戳。

为了改变这种情况,我们又从功能的一个ArrayAdapter:而是采取在一个香草对象数组显示的适配器,ParseQueryAdapter QueryFactory也可以将一个类,它返回一个ParseQuery你定义。通过到构造函数,然后使用该适配器将查询来确定哪些对象来获取和显示。

见下文为例建立一个ParseQueryAdapter仅显示朋克和金属乐队有四个或更多的成员,根据销售的记录数:)

ParseQueryAdapter<ParseObject> adapter =

  newParseQueryAdapter<ParseObject>(this,newQueryFactory<ParseObject>() {

    publicParseQuery get() {

      // Here we can configure a ParseQuery to our heart's desire.

      ParseQuery query =newParseQuery("Band");

      query.whereContainedIn("genre", Arrays.asList({"Punk","Metal"}));

      query.whereGreaterThanOrEqualTo("memberCount",4);

      query.orderByDescending("albumsSoldCount");

      returnquery;

    }

  });

Customizing the Rows(制定行)

The default layout for the individual Views in your AdapterView is a simple LinearLayout with a ParseImageView and a TextView. IfsetTextKey(String) is used with the ParseQueryAdapter, its parameter will be used to select which key on your ParseObject is displayed in the TextView. Similarly, if setImageKey(String) is used, its parameter will be used to determine the image displayed in the ImageView.

One way to customize the rows is to override getItemView(ParseObject, View, ViewGroup) or getNextPageView(View, ViewGroup)and call the superclass's implementation of the appropriate method to do the heavy lifting. If you provide your own layout to the superclass's implementation, note that getItemView(ParseObject, View, ViewGroup) and getNextPageView(View, ViewGroup)expect a TextView (id: android.R.id.text1) if the textKey is set and a ParseImageView (id: android.R.id.icon) if the imageKey is set.

Here, we inflate and configure a layout of our own, with a TextView, a ParseImageView, and an extra "description" TextView (id:R.id.description):

(默认的布局对个人的观点在你是一个简单的LinearLayout AdapterView之间扮演着与一个和一个TextView ParseImageView。 IfsetTextKey(字符串)是用ParseQueryAdapter,其参数将用于选择键在你的ParseObject显示在TextView。 同样,如果setImageKey(字符串)是使用,它的参数将用于确定图像显示在ImageView。

一个方法来定制行是覆盖getItemView(ParseObject、视图节点,而ViewGroup)或getNextPageView(视图节点,而ViewGroup)和调用父类的实现适当的方法来承担这个重任。 如果你提供你自己的布局到父类的实现,注意,getItemView(ParseObject、视图节点,而ViewGroup)和getNextPageView(视图节点,而ViewGroup)期望一个TextView(id:android r id text1)如果textKey设置和一个ParseImageView(id:android r id图标)如果imageKey设置。

在这里,我们膨胀和配置一个布局自己的,一个TextView,ParseImageView,和一个额外的“描述”TextView(id:r id描述):)

@Override

publicView getItemView(ParseObject object, View v, ViewGroup parent) {

  if(v ==null) {

    v = View.inflate(getContext(), R.layout.adapter_item,null);

  }

 

  // Take advantage of ParseQueryAdapter's getItemView logic for

  // populating the main TextView/ImageView.

  // The IDs in your custom layout must match what ParseQueryAdapter expects

  // if it will be populating a TextView or ImageView for you.

  super.getItemView(object, v, parent);

 

  // Do additional configuration before returning the View.

  TextView descriptionView = (TextView) v.findViewById(R.id.description);

  descriptionView.setText(object.getString("description"));

  returnv;

}

Another way to customize the rows is to have complete control over the look of the rows by overriding ParseQueryAdapter's methods and ignoring the superclass's implementation entirely. In this example, our item views are simply rows where the color is defined by theParseObject:

(另一种方法来定制行完全控制的样子行ParseQueryAdapter通过覆盖超类的方法和忽视的实现完全。在这个例子中,我们的项目视图仅仅是颜色的行theParseObject被定义为:)

@Override

publicView getItemView(ParseObject object, View v, ViewGroup parent) {

  if(v ==null) {

    v = View.inflate(getContext(), R.layout.adapter_item,null);

  }

  v.setBackgroundColor(object.getInt("color"));

  returnv;

}

 

@Override

publicView getNextPageView(View v, ViewGroup parent) {

  if(v ==null) {

    // R.layout.adapter_next_page contains an ImageView with a custom graphic

    // and a TextView.

    v = View.inflate(getContext(), R.layout.adapter_next_page,null);

  }

  TextView textView = (TextView) v.findViewById(R.id.nextPageTextViewId);

  textView.setText("Loaded "+ getCount() +" rows. Get more!");

  returnv;

}

Loading Remote Images in Rows(加载远程图像行)

ParseQueryAdapter makes it simple to display remote images. By calling setImageKey(String), you can pass in a key name on yourParseObject which should contain a ParseFile containing an image to be fetched from Parse and loaded into the ParseImageView of the corresponding row.

The image will download asynchronously, and the appropriate ParseImageView will be updated in the background. As the user scrolls and rows are recycled by the adapter, images will be fetched as rows become visible and assigned ParseObjects.

You can define a placeholder image to be used when the image fetch has not yet completed. Call setPlaceholder(Drawable) on yourParseQueryAdapter to use the specified Drawable as a fallback image.

(ParseQueryAdapter使它简单的显示远程图像。 通过调用setImageKey(字符串),您可以通过在一个关键的名字,应该包含一个yourParseObject ParseFile包含一个图像读取从解析和加载到ParseImageView相应的行。

图像将异步下载,和适当的ParseImageView将在后台更新。当用户滚动和行利用适配器,将获取的图像作为行变得越来越清晰,ParseObjects分配。

您可以定义一个占位符图像被用来当图像获取尚未完成。叫setPlaceholder(绘图)在yourParseQueryAdapter使用指定的绘图作为一个后备形象。)

Lifecycle Methods(生命周期方法)

We expose two hooks in the data lifecycle of the Adapter for you to execute custom logic — right before we query Parse for your data and right after the fetched objects have been loaded from the query. These methods are particularly useful for toggling some loading UI.

An OnQueryLoadListener can be set via setOnQueryLoadListener(OnQueryLoadListener), which provides onLoading() andonLoaded(List, Exception) methods for implementation.

(我们暴露在数据生命周期的两个钩子的适配器给你执行自定义逻辑——就在我们查询解析为数据和正确获取对象后加载从查询。这些方法非常有用,特别是一些加载界面之间切换。

可以设置一个OnQueryLoadListener通过setOnQueryLoadListener(OnQueryLoadListener),它提供了装货()andonLoaded(列表,例外)方法来实现。)

Pagination

Pagination ensures that the table only gets one page of objects at a time. You can set the number of objects are in a page by callingsetObjectsPerPage(int).

The query is automatically altered to apply pagination, and a pagination row appears at the bottom of the AdapterView to allow users to load the next page.

Pagination is turned on by default. To turn it off, call setPaginationEnabled(false). With pagination turned off, the ParseQueryAdapterwill use the default ParseQuery limit of 100 items.

(Pagination ensures that the table only gets one page of objects at a time. You can set the number of objects are in a page by callingsetObjectsPerPage(int).

The query is automatically altered to apply pagination, and a pagination row appears at the bottom of the AdapterView to allow users to load the next page.

Pagination is turned on by default. To turn it off, call setPaginationEnabled(false). With pagination turned off, the ParseQueryAdapterwill use the default ParseQuery limit of 100 items.

(分页确保表只能一页的对象在一个时间。你可以设置对象的数量在一个页面,callingsetObjectsPerPage(int)。

查询自动调整应用分页,和一个分页行底部出现AdapterView之间扮演着允许用户加载下一页。

分页是默认打开。关机,打电话给setPaginationEnabled(false)。 与分页关掉,ParseQueryAdapterwill使用默认ParseQuery限制为100项。)

Auto-loading of Data

When the AdapterView that your ParseQueryAdapter is set on is attached to a window, the ParseQueryAdapter's loadObjects() method is automatically called, triggering the fetching of the first page of results. To disable this behavior (perhaps to delay the fetching of data, or run some custom logic ahead of time), just call setAutoload(false) and call loadObjects() manually if autoload is disabled.

(当你的ParseQueryAdapter AdapterView之间扮演着被设置在连接到一个窗口,ParseQueryAdapter的loadObjects()方法调用,自动触发抓取的第一页的搜索结果。 禁用此行为(也许是为了延迟抓取的数据,或运行一些自定义逻辑提前),就叫setAutoload(假),叫loadObjects()手动如果禁用自动加载。)

Handling Errors(处理错误)

Many of the methods on ParseObject, including save()delete(), and get() will throw a ParseException on an invalid request, such as deleting or editing an object that no longer exists in the cloud, or when there is a network failure preventing communication with the Parse Cloud. You will need to catch and deal with these exceptions.

For more details, look at the Android API.

(在ParseObject的许多方法,包括save()、删除()和get()将抛出ParseException在一个无效的请求,比如删除或编辑一个对象,不再存在于云中,或当有一个网络故障预防沟通与解析云。你将需要捕捉和处理这些异常。

为更多的细节,看看 Android API.)

Security(安全性)

We strongly recommend that you build your applications to restrict access to data as much as possible. With this in mind, we recommend that you enable automatic anonymous user creation and specify a default ACL based upon the current user when your application is initialized. Explicitly set public writability (and potentially public readability) on an object-by-object basis in order to protect your data from unauthorized access.

Consider adding the following code to your application startup:

(我们强烈建议您构建您的应用程序来限制访问尽可能多的数据。有鉴于此,我们建议您启用自动匿名用户创建anonymous user creation 并指定一个默认的ACL基于当前用户pecify a default ACL based upon the current user当你初始化应用程序。 显式地设置公共可写性(和潜在的公共可读性)在一个对象的对象基础为了保护你的数据从未经授权的访问。

考虑添加下面的代码到你的应用程序启动:)

ParseUser.enableAutomaticUser();

ParseACL defaultACL =newParseACL();

// Optionally enable public read access while disabling public write access.

// defaultACL.setPublicReadAccess(true);

ParseACL.setDefaultACL(defaultACL,true);

Please keep secure access to your data in mind as you build your applications for the protection of both you and your users.

(请保持安全的访问你的数据在心里为你建立你的应用程序保护你们和你们的用户。)

Settings(设置)

In addition to coding securely, please review the settings pages for your applications to select options that will restrict access to your applications as much as is appropriate for your needs. For example, if users should be unable to log in without a Facebook account linked to their application, disable all other login mechanisms. Specify your Facebook application IDs, Twitter consumer keys, and other such information to enable server-side validation of your users' login attempts.

(除了编码安全,请检查设置页面,为您的应用选择选项,将限制访问您的应用程序一样适合你的需要。例如,如果用户应该无法登录Facebook账户没有链接到他们的应用程序,禁用所有其他登录机制。指定你的Facebook应用程序id,Twitter和其他此类消费者密钥信息,使服务器端验证你的用户的登录尝试。)