If you want to create an app faster, and you do not have knowledge from the backend area, but you require your app to interact with a database, one accessible solution is to use Parse Server. Parse Server is an open source Back-as-a Service (BaaS) framework initially developed by Facebook which uses web-based, all-in-one Dashboard. From here, you can create classes and manage your data, to view analytics, and send push notifications.
As you know, the Parse Service was shut down in January 30, 2017 (I hope you have migrated to other backend service you decided to).
An easy solution for this problem is using Back4app, which is an open source backend that already uses framework and helps developers to build their apps scalable and extensible at a much faster speed. Back4app is great for developers if they are looking for flexibility, customization on source code and the capability to integrate their app with other cloud services.
First of all, storing data on Parse is built around the ParseObject. Each ParseObject is defined as a Json-compatible data which contains key-value pairs, and you don’t need to specify from the beginning what keys exist on each ParseObject; you simply set whatever key-value pairs you want, and Back4app backend will store it.
1. Sign up
I think that if you want to use Back4app, one of the things your app will do is probably register the users. The following code show you a quintessential sign up:
/// <summary> /// Sign up /// </summary> /// <param name="newUser"></param> public void SignUp(User newUser) { var parseUser = new ParseUser(); parseUser["username"] = newUser.Username; parseUser["password"] = newUser.Password; parseUser["email"] = newUser.Email; parseUser["phone"] = newUser.PhoneNumber; var signUpTask = parseUser.SignUpAsync(); signUpTask.ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { Debug.Log("The sign up failed. Check the error to see why"); } else { Debug.Log("Sign up was successful"); } }); }
This method will asynchronously create a new user, but before the user will be saved, it also checks if both the username and email are unique.
Back4app never store user's password in plaintext, but it securely hashes the password using bcrypt. If a signup isn’t successful the most likely is that the username or email has already been taken by another user, but you can catch the exception thrown by the call.
2. Login
After your app is able to let users to sign up, you need to let them log in to their account. The following code illustrates a typical login:
/// <summary> /// Log in /// </summary> /// <param name="username"></param> /// <param name="password"></param> public void Login(string username, string password) { var loginTask = ParseUser.LogInAsync(username, password); loginTask.ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { Debug.Log("The login failed. Check the error to see why"); } else { Debug.Log("Login was successful"); } }); }
It would be silly if the user had to log in every time they open your app. You can avoid this by using the cached ParseUser.CurrentUser object.
Every time you use any signup or login methods, the user is cached on disk. You can think about this cache as a session, and you can assume the user is logged in.
3. Login/Sign up Facebook
Many apps let their users to login/sign up with Facebook account. Parse provides an easy way to integrate Facebook with your app and to be able to provide a “Signup with Facebook” or “Login with Facebook” option into your app. For doing this you must have Facebook SDK into your Unity project and request permission from user to get an access token and their Facebook ID. The following code illustrates a typical login with Facebook:
/// <summary> /// Login Facebook /// </summary> /// <param name="facebookID"></param> /// <param name="accesToken"></param> /// <param name="tokenExpiration"></param> public void LoginFacebook(string facebookID, string accesToken, DateTime tokenExpiration) { var logInTask = ParseFacebookUtils.LogInAsync(facebookID, accesToken, tokenExpiration); logInTask.ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { Debug.Log("The login failed. Check the error to see why"); } else { Debug.Log("Login was successful"); } }); }
When this code is running, Back4app receives the data we send it, and saves it to a ParseUser. If another user is not found based on the Facebook ID, then that user is created.
4. Basic Queries
You have already seen how a user can login/sign up, but sometime it is not enough to have just those two options when to operate with a database; you want to retrieve some information about users. For example, I create from Dashboard another class (table) named Leaderboard and I will save here each user’s score.
/// <summary> /// Save leaderboard score /// </summary> /// <param name="score"></param> public void SaveLeaderboardScore(int score) { if (ParseUser.CurrentUser == null) Debug.Log("You must login with an existing account"); var newScore = new ParseObject("Leaderboard") { { "score", score}, { "username", ParseUser.CurrentUser.Username } }; newScore.SaveAsync().ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { Debug.Log("New score failed from be saved. Check the error to see why"); } else { Debug.Log("New score was successfully saved"); } }); }
Now we can retrieve many objects at once, put conditions on the objects we wish to retrieve. For example, we want to see all users who have a score greater than _value.
/// <summary> /// Shows user with a greater score than /// </summary> /// <param name="minScore"></param> public void ShowUsersWithGreaterScore(int minScore) { var query = ParseObject.GetQuery("Leaderboard"); query.WhereGreaterThan("score", minScore).FindAsync().ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { Debug.Log("The user request failed. Check the error to see why"); } else { IEnumerable<ParseObject> leaderboardObjects = t.Result; foreach (var obj in leaderboardObjects) { // retrieve data from ParseObject var username = obj.Get<string>("username"); var score = obj.Get<int>("score"); Debug.Log(username + " : " + score); } } }); }
We retrieve all objects from class (table) Leaderboard where their score from column score is greater than minScore and we give it as parameter to method.
If you need to retrieve some data from a user you must create a query for users. You need to use the special user query like this:
/// <summary> /// Shows user from a specific city /// </summary> /// <param name="city"></param> public void ShowUserFromSpecificCity(string city) { var query = ParseUser.Query.WhereEqualTo("city", city); query.FindAsync().ContinueWith(t => { if (t.IsFaulted || t.IsCanceled) { Debug.Log("The user request failed. Check the error to see why"); } else { IEnumerable<ParseUser> users = t.Result; foreach (var user in users) { Debug.Log(user.Username); } } }); }
You can do complex queries like:
1. Query Constraints
-
WhereNotEqualTo
-
WhereGreaterThan
-
FirstAsync or FirstOrDefaultAsync
-
OrderBy etc.
2. Relational Queries
-
a. WhereExists
-
b. WhereMatchesQuery
Conclusion:
If I caught your attention with those simple examples of things you can do using Unity3D as a development platform and Back4app as a backend service then you can keep into your mind this option when you want to build an app.
References:
http://docs.parseplatform.org/unity/guide
https://github.com/back4app/parse-server